Dennis Byrne
Introduction to Unit Test gPart 2 of 2
Agenda …
● mock()
● when()
● verify()
● ArgumentCaptor
● reset()
Encapsulation, Encapsulation, Encapsulation
Law of Demeter
● Each unit should have only limited knowledge about other units:
only units "closely" related to the current unit.
● Each unit should only talk to its friends; don't talk to strangers.
● Only talk to your immediate friends.
Mockito.mock()
@Test
public void lawOfDemeterBroken(){
Person gnan = mock(Person.class);
Pants pants = mock(Pants.class);
Wallet wallet = mock(Wallet.class);
Collection<Bill> bills = mock(Collection.class);
Bill bill = mock(Bill.class);
Iterator<Bill> iterator = mock(Iterator.class);
// …
Mockito.when()
// …
when(gnan.getPants()).thenReturn(pants);
when(pants.getWallet()).thenReturn(wallet);
when(wallet.getBills()).thenReturn(bills);
when(bills.iterator()).thenReturn(iterator);
when(iterator.hasNext()).thenReturn(true);
when(iterator.next()).thenReturn(bill);
when(bill.getValue()).thenReturn(5);
Law of Demeter: broken
// ...
Person dennis = new Person();
borrow(gnan, dennis, 5);
assertTrue(dennis.getPants().getWallet().getBills().contains(bill));
}
Law of Demeter: broken public static void borrow(Person from, Person to, int amount){
Iterator<Bill> iterator =
from.getPants().getWallet().getBills().iterator();
while (iterator.hasNext()) {
Bill bill = iterator.next();
if(bill.getValue() == amount){
iterator.remove();
to.getPants().getWallet().getBills().add(bill);
break;
}
}
}
Law of Demeter: fixed
@Test
public void lawOfDemeter(){
Person gnan = mock(Person.class);
when(gnan.removeMoneyAmount(anyInt())).thenReturn(new Bill(5));
Person dennis = new Person();
dennis.borrow(5, gnan);
assertEquals(5, dennis.getMoneyTotal());
}
“Test First” Running Total
1
Law of Demeter
public String methodChain(){
StringBuilder builder = new StringBuilder();
builder.append("this")
.append("doesn't")
.append("break")
.append("encapsulation");
return builder.toString();
}
Agenda …
● mock()
● when()
● verify()
● ArgumentCaptor
● reset()
Testing behavior/interactions @Test public void behaviorBad() {
FederatedSearchServer searchServer = new FederatedSearchServer(){
private int callCount = 0;
@Override public List<JSONObject> doPeopleNameSearch(String name) {
if(callCount++ > 0)
Assert.fail();
return super.doPeopleNameSearch(name);
}
};
VoltronServer voltron = new VoltronServer(searchServer);
voltron.doPeopleNameSearch("conan");
voltron.doPeopleNameSearch("conan");
}
“Test First” Running Total
2
“Test First” Running Total
3
Mockito.verify @Test
public void behavior(){
FederatedSearchServer searchServer = mock(FederatedSearchServer.class);
when(searchServer.doPeopleNameSearch("conan")).thenReturn(new
LinkedList<JSONObject>());
VoltronServer voltron = new VoltronServer(searchServer);
voltron.doPeopleNameSearch("conan");
voltron.doPeopleNameSearch("conan");
verify(searchServer, times(1)).doPeopleNameSearch("conan");
// atLeast(n) anyString()
// atMost(n)
// never()
}
“Test First” Running Total
4
Agenda … Mockito
● mock()
● when()
● verify()
● ArgumentCaptor
● reset()
Mockito - ArgumentCaptor
@Test
public void argumentCaptor() {
FederatedSearchServer searchServer = mock(FederatedSearchServer.class);
VoltronServer voltronServer = new VoltronServer(searchServer);
voltronServer.doPeopleNameSearch("conan");
ArgumentCaptor<PeopleSearchRequest> captor = forClass(PeopleSearchRequest.class);
verify(searchServer).doPeopleNameSearch(captor.capture());
PeopleSearchRequest passedToSearchServer = captor.getValue();
assertEquals("conan", passedToSearchServer.getSearchTerm());
}
Agenda … Mockito
● mock()
● when()
● verify()
● ArgumentCaptor
● reset()
TestNG vs. JUnit
private FederatedSearchServer searchServer =
mock(FederatedSearchServer.class);
@Test
public void searchWithStemming(){
VoltronServer voltronServer = new VoltronServer(searchServer);
List<JSONObject> results = voltronServer.doPeopleNameSearch("con");
assertEquals(results.get(0).get("name"), "Conan O'Brian");
}
TestNG vs. JUnit
@Test
public void searchWithFullName(){
List<JSONObject> hits = new LinkedList<JSONObject>();
hits.add(new JSONObject("Conan O'Brian"));
when(searchServer.doPeopleNameSearch(anyString())).thenReturn(hits);
VoltronServer voltronServer = new VoltronServer(searchServer);
List<JSONObject> results =
voltronServer.doPeopleNameSearch("conan");
assertEquals(results.get(0).get("name"), "Conan O'Brian");
}
TestNG vs. JUnit
@AfterMethod
public void afterMethod(){
reset(this.searchServer);
}
“Test First” Running Total
5
Agenda … Mockito
● mock()
● when()
● verify()
● ArgumentCaptor
● reset()