Как издеваться над процессором Camel в тесте JUnit - PullRequest
0 голосов
/ 03 сентября 2018

Я столкнулся с проблемой, когда мне было поручено создать тест JUnit для одного из моих верблюжьих процессоров.

Основной класс выглядит следующим образом: (лишние вещи опущены).

@Stateless
@Named
public class CalculateProportionalAmount implements Plugin{ // where Plugin is our interface extending a Processor
LocalDate now;

@Override
public void process(final Exchange exchange) throws Exception{
    now = getNow();
    int startDay = getValueOfInputParameter("start") //just gets 1-31 from input parameters on exchange
    int value = getValueOfInputParameter("value") //gets value from input parameters
/*
More kind-of irrelevant lines of code. Idea is that the processor calculates number of days between "now" and startDay, calculates what proportion of month this amount of days is and applies this proportion to the value. 

So if today would be 1st and startDay is 10th (so 10 days between) when September has 30 days and value = 1000, the processor would calculate (10/30)*1000 
*/
}

public LocalDate getNow(){
    return LocalDate.now();
}
}

А для тестового класса:

public class CalculateProportionalAmountTest{
Plugin plugin; 

@Before
public void setUp(){
   //inicialize parameter maps, instantiate the plugin, so that we can reference it. "plugin" value is then instance of the "CalculateProportionalAmount" class.
}

    @Test
    public void pluginTestNextMonth() throws Exception {

        Mockito.when(((CalculateProportionalAmount) plugin).getNow()).thenReturn(LocalDate.of(2017, 12, 11)); //obviously does not work, because plugin is not mocked.... 

        ruleParameter.put("start", "10"); //here we set the "start" param that processor class gets.
        ruleParameter.put("value", "1000"); //here we set the "value" param that processor class gets.
        Exchange prepareInput = prepareExchange(scenarioParameters, ruleParameter);
        Exchange output = execute(prepareInput);

        String resultString = getScenarioParameterByKey(output, "result");
        TestCase.assertEquals(String.format("%.6f", Double.valueOf(1000) * 30 / 31), resultString); //obviously will not pass unless on 11th of December
    }
}

Моя самая большая проблема заключается в том, что метод getNow() вызывается и должен вызываться внутри метода process, перезаписывая любые попытки указать дату.

Вычисление «реальных» пропорций также недопустимо, так как мы должны иметь возможность проверять варианты «позднее в этом месяце», «ранее в этом месяце» и «сегодня» в любой день.

Самое подходящее решение, которое у меня сейчас есть, - это настроить (смоделировать) метод getNow(), чтобы он возвращал определенную дату при вызове из теста, но мне нужно оставить метод процесса работать, как написано, без каких-либо насмешек. ,

Проект, частью которого он является, уже использует Mockito, но я не очень разбираюсь в том, как он работает и как правильно издеваться над классом, чтобы он работал, как описано выше. Я уже предпринял попытку сделать это в начале тестового класса, но в настоящее время он заканчивается исключением, и с тех пор я просматривал учебники без особой удачи.

Спасибо за помощь

Ответы [ 3 ]

0 голосов
/ 03 сентября 2018

Mockito предлагает частичные имитации для имитации методов типа getNow и вызова реальной реализации для других методов.

0 голосов
/ 03 сентября 2018

Чтобы правильно проверить верблюжий маршрут, вы должны расширить класс CamelTestSupport из пакета верблюда. В общем, они предоставляют поддержку для тестирования верблюда.

Мой совет - создать собственный маршрут:

@Override
protected RoutesBuilder createRouteBuilder() {
    return new RouteBuilder() {
        @Override
        public void configure() {

            from( "direct:testRoute" )
                    .process( new YourPluginClass() )
                    .end();
        }
    };
}

Тогда вы сможете вызывать его с fluentTemplate из CamelTestSupport класса и правильно тестировать процессор.

Чтобы смоделировать поведение процессора (частично), используйте шпиона из Mockito, как сказал @drowny. Имейте в виду, что если вы хотите использовать аннотацию @Spy, вы должны инициировать ее с помощью строки MockitoAnnotations.initMocks(this) в методе настройки @Before.

0 голосов
/ 03 сентября 2018

Вы можете использовать @Spy, я думаю.

@Spy
Plugin plugin; 

И затем в вашем методе тестирования вы можете манипулировать с помощью doReturn для этого открытого метода

Mockito.doReturn(LocalDate.of(2017, 12, 11)).when((CalculateProportionalAmount) plugin).getNow();
Тег

@Spy относится к реальному объекту, и вы можете изменить методы возврата объекта-шпиона.

...