Я пишу модульные тесты для старого кода, где класс использует Apache Beam, вызывающий другие службы внешних классов (которые я не написал или не могу изменить). Классы не используют интерфейсы.
Код: Выделить всё
public class DataAdapter extends DoFn{
public String processCategory;
public Map configs;
public ServiceApi serviceApi;
public DataAdapter(String processCategory, Map configs) {
this.processCategory = processCategory;
this.configs = configs;
}
@Setup
public void init() {
serviceApi = new ServiceApi(processCategory, configs);
}
@ProcessElement
public void processData(ProcessContext context, @Element KV input) {
try {
String productId = input.getKey();
serviceApi.getData();
....
}
}
Я создал подделку ниже. Вызов конструкторов с нулевыми значениями приведет к ошибкам исключения аргументов в конструкторе serviceApi. Итак, я попробовал шаблон создания фабрики, который, вероятно, не идеален. (пытается найти другое решение)
Однако подделка продолжает переопределяться, поскольку для каждого ProcessElement он вызывает программу установки с повторной инициализацией родительского класса. Нам пришлось инициализировать каждый пакет установки, поскольку serviceApi не подлежал сериализации при запуске приложения Apache Beam.
Создать подделку:
Код: Выделить всё
public class ServiceApiFake extends ServiceApi {
public ServiceApiFake() {
super(null, null);
}
public static ServiceApiFake create() {
try {
return new ServiceApiFake();
} catch (Exception ignore) {
return null;
}
}
@Override
public DataItem getData(String keyId) {
return null;
}
}
Код: Выделить всё
TestStream testStream = TestStream.create(KvCoder.of(StringUtf8Coder.of(), SerializableCoder.of(Product.class)))
.addElements(KV.of("25", product)).advanceWatermarkToInfinity();
DataAdapter dataAdapter = new DataAdapter("productCategory", configs);
dataAdapter.serviceApi = new ServiceApiFake();
pipeline.apply(testStream).apply(ParDo.of(dataAdapter));
pipeline.run();
возвращается к вызову обычной службы при установке вместо фиктивной.
Я подумал о том, чтобы вернуться к тестированию методов по отдельности, вызвав метод «processData» без вызова установки и используя макет Mockito для ProcessContext, ElementInput и serviceApi, когда (serviceApi .getData()).thenReturn(..) . Эта стратегия на самом деле работает, она не идеальна, но позволяет мне в некоторой степени тестировать.
Я бы хотел, чтобы у команды Apache Beam была лучшая и надежная альтернатива использованию подделок или каким-то образом позволяла использовать макеты. Или снова разрешите DoFnTester (поскольку в настоящее время он устарел). Политика компании больше не допускает устаревшего использования.
Ресурс: Я просмотрел ссылку на статью stackoverflow. Их serviceAPI не имеет переменных-конструкторов или средств проверки исключений аргументов внутри serviceAPI, поэтому он работает в их ситуации.
Apache Beam имитирует внешние клиенты, инициализированные в методе @Setup Lifecycle DoFn< /п>
Подробнее здесь: https://stackoverflow.com/questions/784 ... f-dofn-wit