【发布时间】:2014-12-28 14:09:22
【问题描述】:
我是单元测试和 Mockito 的新手。我对应该测试和验证的内容感到困惑。我有一个 A 类如下:
public class A{
@Autowired
private B b;
public double doSomething(Request r){
r = b.process1(r);
r = b.process2(r);
return calculateFinal(r);
}
public void reportSomething(Request r){
r = b.process1(r);
r = b.process2(r);
b.report(r);
}
private int calculateFinal(Request r){
return r.getFinalScore() * 2;
}
}
假设我想用 Junit 测试来测试这两种方法。因为我在 A 中有一个依赖项 B,所以我用 Mockito 模拟它。对于这两个测试,我都被告知我应该假设依赖项 b 已经过全面测试并且可以正常工作,因为我们要测试 A 中的业务逻辑。
起初看起来我不需要为reportSomething() 测试任何东西,因为它只涉及对b 的调用并且它们都在“工作”?我能想到的唯一要测试的是它们是否真的被调用以及调用的顺序,对吗?那么我应该调用 a.reportSomething() 然后进行验证吗?让我烦恼的一件事是我是否应该存根 b.process1() 和 b.process2() 以返回任何内容。我试过没有存根任何东西,但它起作用了,但为什么呢?
对于testDoSomething(),我想我真正测试的是calculateFinal() 方法。但由于它使用来自 Request 对象的数据,我需要先在 Request r 中设置该数据。由于r 直接来自b.process2(),我应该存根方法调用以返回带有该数据的请求对象。但我可以跳过b.process1() 的存根,对吧?
这是一个正确的思考过程吗?我错过了什么或误解了什么?如果是对的,有没有更好更干净的写法呢?谢谢!
public class ATest{
private static final int SCORE = 100;
@Mock
private B mockB;
@InjectMocks
private A aClient;
@Before
public void setUpTest{
MockitoAnnotations.initMocks(this);
}
@Test
public void testReportSomething(){
// what should I test here?
Request r = new Request();
// is it necessary to include the following two lines?
when(mockB.process1(any(Request.class))).return(r);
when(mockB.process2(any(Request.class))).return(r);
aClient.reportSomething(r);
InOrder inOrder = inOrder(mockProcesser);
inOrder.verify(mockProcesser).process1(any(Request.class));
inOrder.verify(mockProcesser).process2(any(Request.class));
inOrder.verify(mockProcesser).report(any(Request.class));
}
@Test
public void testDoSomething(){
// Is this correct?
Request r = new Request();
r.setFinal(SCORE);
// I skipped this line and it still works
when(mockB.process1(any(Request.class))).return(r);
when(mockB.process2(any(Request.class))).return(r);
assert(SCORE * 2, aClient.doSomething(r));
// is it still necessary to verify the call to mockB?
}
}
【问题讨论】:
标签: java unit-testing junit mocking mockito