如何在JUnit测试中模拟Camel处理器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在JUnit测试中模拟Camel处理器相关的知识,希望对你有一定的参考价值。

当我的任务是为我的一个骆驼处理器创建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的一部分,但我对它的工作方式以及如何正确地模拟该类以使其如上所述起作用并不是很熟练。我已经尝试在测试类的开头这样做,但它目前以异常结束,我一直在浏览教程,因为没有太多运气。

谢谢你的帮助

答案

你认为你可以使用@Spy

@Spy
Plugin plugin; 

然后在您的测试方法中,您可以使用doReturn操作此公共方法

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

@Spy标签指的是真实对象,你可以改变间谍对象的返回方法。

另一答案

Mockito提供partial mocks来模拟像getNow这样的方法,并为其他方法调用真正的实现。

另一答案

为了正确测试驼峰路线,你应该从驼峰包扩展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行初始化它。

以上是关于如何在JUnit测试中模拟Camel处理器的主要内容,如果未能解决你的问题,请参考以下文章

junit4单元测试--web项目中模拟登录会话,做全流程测试

在 Apache Camel 应用程序中,单元测试如何注入模拟端点来代替真实端点?

如何将JUnit 4测试添加到JUnit 3测试套件中

Spring JUnit:如何在自动装配组件中模拟自动装配组件

通过JUnit进行Android单元测试

MockEJB - JUnit Mockito - 无法在第二个单元测试中重新绑定模拟 EJB