- How to capture an argument which is passed to a mock?
First Snippet
@Test
public void captureArgument() {
ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
TodoService todoService = mock(TodoService.class);
List<String> allTodos = Arrays.asList("Learn Spring MVC", "Learn Spring", "Learn to Dance");
Mockito.when(todoService.retrieveTodos("Ranga")).thenReturn(allTodos);
TodoBusinessImpl todoBusinessImpl = new TodoBusinessImpl(todoService);
todoBusinessImpl.deleteTodosNotRelatedToSpring("Ranga");
Mockito.verify(todoService).deleteTodo(argumentCaptor.capture());
assertEquals("Learn to Dance", argumentCaptor.getValue());
}
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.in28minutes.mockito</groupId>
<artifactId>mockito-tutorial</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
package com.in28minutes.business;
import java.util.ArrayList;
import java.util.List;
import com.in28minutes.data.api.TodoService;
public class TodoBusinessImpl {
private TodoService todoService;
TodoBusinessImpl(TodoService todoService) {
this.todoService = todoService;
}
public List<String> retrieveTodosRelatedToSpring(String user) {
List<String> filteredTodos = new ArrayList<String>();
List<String> allTodos = todoService.retrieveTodos(user);
for (String todo : allTodos) {
if (todo.contains("Spring")) {
filteredTodos.add(todo);
}
}
return filteredTodos;
}
public void deleteTodosNotRelatedToSpring(String user) {
List<String> allTodos = todoService.retrieveTodos(user);
for (String todo : allTodos) {
if (!todo.contains("Spring")) {
todoService.deleteTodo(todo);
}
}
}
}
package com.in28minutes.data.api;
import java.util.List;
// External Service - Lets say this comes from WunderList
public interface TodoService {
public List<String> retrieveTodos(String user);
void deleteTodo(String todo);
}
package com.in28minutes.business;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import com.in28minutes.data.api.TodoService;
public class TodoBusinessImplMockitoTest {
@Test
public void usingMockito() {
TodoService todoService = mock(TodoService.class);
List<String> allTodos = Arrays.asList("Learn Spring MVC",
"Learn Spring", "Learn to Dance");
when(todoService.retrieveTodos("Ranga")).thenReturn(allTodos);
TodoBusinessImpl todoBusinessImpl = new TodoBusinessImpl(todoService);
List<String> todos = todoBusinessImpl
.retrieveTodosRelatedToSpring("Ranga");
assertEquals(2, todos.size());
}
@Test
public void usingMockito_UsingBDD() {
TodoService todoService = mock(TodoService.class);
TodoBusinessImpl todoBusinessImpl = new TodoBusinessImpl(todoService);
List<String> allTodos = Arrays.asList("Learn Spring MVC",
"Learn Spring", "Learn to Dance");
//given
given(todoService.retrieveTodos("Ranga")).willReturn(allTodos);
//when
List<String> todos = todoBusinessImpl
.retrieveTodosRelatedToSpring("Ranga");
//then
assertThat(todos.size(), is(2));
}
@Test
public void letsTestDeleteNow() {
TodoService todoService = mock(TodoService.class);
List<String> allTodos = Arrays.asList("Learn Spring MVC",
"Learn Spring", "Learn to Dance");
when(todoService.retrieveTodos("Ranga")).thenReturn(allTodos);
TodoBusinessImpl todoBusinessImpl = new TodoBusinessImpl(todoService);
todoBusinessImpl.deleteTodosNotRelatedToSpring("Ranga");
verify(todoService).deleteTodo("Learn to Dance");
verify(todoService, Mockito.never()).deleteTodo("Learn Spring MVC");
verify(todoService, Mockito.never()).deleteTodo("Learn Spring");
verify(todoService, Mockito.times(1)).deleteTodo("Learn to Dance");
// atLeastOnce, atLeast
}
@Test
public void captureArgument() {
ArgumentCaptor<String> argumentCaptor = ArgumentCaptor
.forClass(String.class);
TodoService todoService = mock(TodoService.class);
List<String> allTodos = Arrays.asList("Learn Spring MVC",
"Learn Spring", "Learn to Dance");
Mockito.when(todoService.retrieveTodos("Ranga")).thenReturn(allTodos);
TodoBusinessImpl todoBusinessImpl = new TodoBusinessImpl(todoService);
todoBusinessImpl.deleteTodosNotRelatedToSpring("Ranga");
Mockito.verify(todoService).deleteTodo(argumentCaptor.capture());
assertEquals("Learn to Dance", argumentCaptor.getValue());
}
}
package com.in28minutes.business;
import static org.junit.Assert.assertEquals;
import java.util.List;
import org.junit.Test;
import com.in28minutes.data.api.TodoService;
import com.in28minutes.data.stub.TodoServiceStub;
public class TodoBusinessImplStubTest {
@Test
public void usingAStub() {
TodoService todoService = new TodoServiceStub();
TodoBusinessImpl todoBusinessImpl = new TodoBusinessImpl(todoService);
List<String> todos = todoBusinessImpl
.retrieveTodosRelatedToSpring("Ranga");
assertEquals(2, todos.size());
}
}
package com.in28minutes.data.stub;
import java.util.Arrays;
import java.util.List;
import com.in28minutes.data.api.TodoService;
public class TodoServiceStub implements TodoService {
public List<String> retrieveTodos(String user) {
return Arrays.asList("Learn Spring MVC", "Learn Spring",
"Learn to Dance");
}
public void deleteTodo(String todo) {
}
}
package com.in28minutes.mockito;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
public class FirstMockitoTest {
@Test
public void test() {
assertTrue(true);
}
}
package com.in28minutes.mockito;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.List;
import org.junit.Test;
import org.mockito.Mockito;
public class ListTest {
@Test
public void letsMockListSize() {
List list = mock(List.class);
when(list.size()).thenReturn(10);
assertEquals(10, list.size());
}
@Test
public void letsMockListSizeWithMultipleReturnValues() {
List list = mock(List.class);
when(list.size()).thenReturn(10).thenReturn(20);
assertEquals(10, list.size()); // First Call
assertEquals(20, list.size()); // Second Call
}
@Test
public void letsMockListGet() {
List<String> list = mock(List.class);
when(list.get(0)).thenReturn("in28Minutes");
assertEquals("in28Minutes", list.get(0));
assertNull(list.get(1));
}
@Test(expected = RuntimeException.class)
public void letsMockListGetToThrowException() {
List<String> list = mock(List.class);
when(list.get(Mockito.anyInt())).thenThrow(
new RuntimeException("Something went wrong"));
list.get(0);
}
@Test
public void letsMockListGetWithAny() {
List<String> list = mock(List.class);
Mockito.when(list.get(Mockito.anyInt())).thenReturn("in28Minutes");
// If you are using argument matchers, all arguments
// have to be provided by matchers.
assertEquals("in28Minutes", list.get(0));
assertEquals("in28Minutes", list.get(1));
}
@Test
public void bddAliases_UsingGivenWillReturn() {
List<String> list = mock(List.class);
//given
given(list.get(Mockito.anyInt())).willReturn("in28Minutes");
//then
assertThat("in28Minutes", is(list.get(0)));
assertThat("in28Minutes", is(list.get(0)));
}
}