dimanche 28 décembre 2014

confused by unit testing and Mockito

I'm new to unit test and Mockito. I got confused by what I should test and verify. I have a class A as follows:



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. Since I have a dependency B in A, I mock it with 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.


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"? 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? One thing that bugs me is that whether I should stub the b.process1() and b.process2() to return anything. I tried without stubbing anything and it worked, but why?


For testDoSomething(), I think what I'm really testing is the calculateFinal() method. But since it uses the data from the Request object, I need to set that data in Request r first. Since r directly comes from b.process2(), I should stub the method call to return a Request object with that data. But I could skip the stubbing of b.process1(), right?


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?
}
}

Aucun commentaire:

Enregistrer un commentaire