Reputation: 865
Assume you have three classes A
, B
, and C
where A
calls B
and B
calls C
and every class has some number of internal states that influence the result given by the class' methods. Describe how using Mockito can considerably reduce the number of test cases for class A.
I am new to Mockito. I sort of got the concept of Mockito but stumbled upon the above question for which I do not have an answer.
Upvotes: 2
Views: 171
Reputation: 311163
Mockito can help you isolate a class' behavior without having to know the internal workings of a collaborating class.
Assume C
looks like this:
public class C {
private B b;
public C (B b) {
this.b = b;
}
public boolean isLargerThanTen() {
return b.getSomeCalculation() > 10;
}
}
Now suppose you're testing C.isLargerThanTen()
. Without mocking, you'll have to know how exactly to construct B
so that its getSomeCalculation()
returns such a number. E.g.:
A a = new A();
a.setSomething(1);
a.setSomethingElse(2);
B b = new B(a);
b.setAnotherThing(999);
b.setYetAnotherThing(888);
C c = new C(b);
assertTrue(c.isLargerThanTen());
This is problematic on two fronts - first, it's cumbersome. Second, it makes you know the internal workings of B
(and in this case, A
, which B
depends on too). If B
were to change its implementation, C
's test would break, even though there's nothing wrong with C
, just with the (bad) way its test is set up.
Instead, if you use mocking, you could just simulate the only part of the behavior you care about, without the hassle of understanding the internal implementation details of B
:
B b = Mockito.mock(B.class);
Mockito.when(b.getSomeCalculation()).thenReturn(11);
C c = new C(b);
assertTrue(c.isLargerThanTen());
Upvotes: 4
Reputation: 35598
This sounds like homework, but the advantage to using a mocking framework like Mockito is that it allows you to completely separate the functionality of each component when performing tests. That is, you only need to test the interface presented by A
and the possible scenarios (various inputs, etc) because you can control what the mocked B
and C
classes do.
For example, if you need to test error handling in A
you can simply have your mock B
object throw an exception without having to actually generate the error condition in B
that would have otherwise triggered the exception.
The short answer is because it gives you a greater degree of control over the class under test (and that class's dependencies) and allows you to simulate real-world conditions that would otherwise take a lot more code to generate.
Upvotes: 3