[英]confused by unit testing and Mockito
I'm new to unit test and Mockito. 我是单元测试和Mockito的新手。 I got confused by what I should test and verify.
我对应该测试和验证的内容感到困惑。 I have a class A as follows:
我的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;
}
}
Suppose I want to test these two methods with Junit test. 假设我想用Junit测试来测试这两种方法。 Since I have a dependency B in A, I mock it with Mockito.
因为我在A中有一个依赖项B,所以我用Mockito对其进行了模拟。 For both tests, I was told that I should assume that the dependency b is fully tested and properly working since we want to test the business logic in A.
对于这两个测试,我都被告知我应该假设依赖项b已经过充分测试并且可以正常工作,因为我们要测试A中的业务逻辑。
At first it looks like that I don't have to test anything for reportSomething()
since it only involves calls to b
and they are all "working"? reportSomething()
来,我不需要为reportSomething()
测试任何东西,因为它仅涉及对b
调用,并且它们都在“正常工作”? The only thing I can think of to test is whether they are actually called and the order of the calls, correct? 我唯一想测试的是它们是否真正被调用以及调用的顺序正确吗? So should I just call a.reportSomething() and then do the verification?
那么我应该只调用a.reportSomething()然后进行验证吗? One thing that bugs me is that whether I should stub the b.process1() and b.process2() to return anything.
让我感到困扰的一件事是,是否应该对b.process1()和b.process2()进行存根以返回任何内容。 I tried without stubbing anything and it worked, but why?
我试着不存anything任何东西,它奏效了,但是为什么呢?
For testDoSomething(), I think what I'm really testing is the calculateFinal() method. 对于testDoSomething(),我认为我真正测试的是calculateFinal()方法。 But since it uses the data from the Request object, I need to set that data in Request
r
first. 但是由于它使用了Request对象中的数据,因此我需要先在Request
r
设置该数据。 Since r
directly comes from b.process2()
, I should stub the method call to return a Request object with that data. 由于
r
直接来自b.process2()
,所以我应该对方法调用进行存根处理以返回带有该数据的Request对象。 But I could skip the stubbing of b.process1()
, right? 但是我可以跳过
b.process1()
的存根,对吗?
Is this a right thinking process? 这是正确的思考过程吗? Did I miss something or misunderstand something?
我错过了什么还是误会了吗? If it's right, is there a better and cleaner way to write it?
如果是正确的话,有没有更好,更干净的方法来编写它? Thank you!
谢谢!
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?
}
}
You are doing your test incorrectly. 您的测试不正确。 Let's look at the method you want to test:
让我们看一下您要测试的方法:
public void reportSomething(Request r){
r = b.process1(r);
r = b.process2(r);
b.report(r);
}
First of all, you need to mock that when b processes a request, it returns the expected result; 首先,您需要嘲笑b处理请求时,它会返回预期结果; DO NOT therefore use the same return value for two invocations.
因此,请勿对两个调用使用相同的返回值。
Here is how I would write the test: 这是我编写测试的方式:
final Request r = mock(Request.class);
final Request r1 = mock(Request.class);
final Request r2 = mock(Request.class);
when(mockB.process1(r)).thenReturn(r1);
when(mockB.process2(r1)).thenReturn(r2);
doNothing().when(mockB).report(any(Request.class));
final InOrder inOrder = inOrder(mockB);
// Launch... And then verify:
inOrder.verify(mockB).process1(r);
inOrder.verify(mockB).process2(r1);
inOrder.verify(mockB).report(r2);
inOrder.verifyNoMoreInteractions();
As to: 关于:
// is it necessary to include the following two lines?
Yes. 是。 By default, when unspecified, a mocked instance will return Java's defaults: 0 for numeric primitives, false for boolean, null for objects.
默认情况下,未指定时,模拟实例将返回Java的默认值:数字基元为0,布尔值为false,对象为null。 You MUST specify what you want to be returned by stubbing.
您必须指定要通过存根返回的内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.