当我负责为一个骆驼处理器创建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()
方法以从测试中调用时返回特定日期,但是我需要使process方法保持编写状态,而无需任何模拟。
该项目的一部分已经使用了Mockito,但是我对它的工作方式以及如何正确模拟类以使其如上所述那样工作不是很熟练。我已经在测试课程的开头尝试过这样做,但是目前它以异常结束,并且我一直在浏览教程,因为运气不佳。
谢谢您的帮助
答案 0 :(得分:2)
我认为您可以使用@Spy
。
@Spy
Plugin plugin;
然后在您的测试方法中,您可以使用doReturn
对此公共方法进行操作
Mockito.doReturn(LocalDate.of(2017, 12, 11)).when((CalculateProportionalAmount) plugin).getNow();
@Spy
标签指向实际对象,您可以更改间谍对象的返回方法。
答案 1 :(得分:0)
Mockito提供partial mocks来模拟HTTP Status 500 - Internal Server Error
type Exception report
messageInternal Server Error
descriptionThe server encountered an internal error that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: java.lang.ClassNotFoundException: con.mysql.jdbc.Driver
root cause
java.lang.ClassNotFoundException: con.mysql.jdbc.Driver
之类的方法,并为其他方法调用真正的实现。
答案 2 :(得分:0)
为了正确测试骆驼路线,您应该从骆驼包中扩展SymmetricalUncertainty
类。通常,它们为测试骆驼提供了支持。
我的建议是创建自定义路线:
CamelTestSupport
然后,您将可以使用@Override
protected RoutesBuilder createRouteBuilder() {
return new RouteBuilder() {
@Override
public void configure() {
from( "direct:testRoute" )
.process( new YourPluginClass() )
.end();
}
};
}
类中的fluentTemplate
进行调用,并正确测试处理器。
为了模拟处理器的行为(部分),请使用@drowny所说的Mockito的间谍程序。请记住,如果要使用CamelTestSupport
批注,则必须使用@Spy
设置方法中的MockitoAnnotations.initMocks(this)
行将其初始化。