package hu.advancedweb.scott;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Iterator;
import org.junit.Test;
import hu.advancedweb.scott.helper.TestHelper;
public class MockitoTest {
@Test
public void simpleMock() throws Exception {
Foo foo = mock(Foo.class);
when(foo.bar()).thenReturn("42");
String result = foo.bar();
assertThat(TestHelper.getLastRecordedStateForVariable("result"), equalTo("42"));
assertEquals("42", result);
verify(foo, times(1)).bar();
}
@Test
public void simpleMockWithConstParam() throws Exception {
Foo foo = mock(Foo.class);
when(foo.bar("42")).thenReturn("42");
String result = foo.bar("42");
assertThat(TestHelper.getLastRecordedStateForVariable("result"), equalTo("42"));
assertEquals("42", result);
verify(foo, times(1)).bar("42");
}
@Test
public void simpleMockWithDynamicParam() throws Exception {
Foo foo = mock(Foo.class);
when(foo.bar(anyString())).thenReturn(anyString());
String result = foo.bar(anyString());
assertThat(TestHelper.getLastRecordedStateForVariable("result"), equalTo("42"));
assertEquals("42", result);
verify(foo, times(1)).bar(anyString());
}
@Test
public void mockInAContainer() throws Exception {
Foo foo = mock(Foo.class);
MockHolder<Foo> holder = new MockHolder<>(foo);
when(foo.bar()).thenReturn("42");
String result = foo.bar();
assertThat(TestHelper.getLastRecordedStateForVariable("result"), equalTo("42"));
assertEquals("42", result);
verify(foo, times(1)).bar();
verify(holder.t, times(1)).bar();
}
@Test
public void mockInAContainer_2() throws Exception {
Foo foo = mock(Foo.class);
MockHolder<Foo> holder = new MockHolder<>(foo);
when(holder.t.bar()).thenReturn("42"); // refering to the mock through the holder object
String result = foo.bar();
assertThat(TestHelper.getLastRecordedStateForVariable("result"), equalTo("42"));
assertEquals("42", result);
verify(foo, times(1)).bar();
verify(holder.t, times(1)).bar();
}
@Test
public void mockInAContainerWithDynamicParam() throws Exception {
Foo foo = mock(Foo.class);
MockHolder<Foo> holder = new MockHolder<>(foo);
when(foo.bar(anyString())).thenReturn("42");
String result = foo.bar(anyString());
assertThat(TestHelper.getLastRecordedStateForVariable("result"), equalTo("42"));
assertEquals("42", result);
verify(foo, times(1)).bar(anyString());
verify(holder.t, times(1)).bar(anyString());
}
@Test
public void mockWithMultipleReturns() throws Exception {
@SuppressWarnings("unchecked")
Iterator<String> i = (Iterator<String>) mock(Iterator.class);
when(i.next()).thenReturn("Hello").thenReturn("Scott");
String result = i.next() + " " + i.next();
assertThat(TestHelper.getLastRecordedStateForVariable("result"), equalTo("Hello Scott"));
assertEquals("Hello Scott", result);
}
@Test(expected = IOException.class)
public void mockWithDoThrow() throws Exception {
OutputStream mock = mock(OutputStream.class);
OutputStreamWriter osw = new OutputStreamWriter(mock);
doThrow(new IOException()).when(mock).close();
osw.close();
}
@Test
public void mockParameterWithVerify() throws Exception {
OutputStream mock = mock(OutputStream.class);
OutputStreamWriter osw = new OutputStreamWriter(mock);
osw.close();
verify(mock).close();
}
@Test
public void simpleSpy() throws Exception {
Foo foo = new FooImpl();
Foo fooSpy = spy(foo);
when(fooSpy.bar()).thenReturn("spy");
String resultOfMockedMethod = fooSpy.bar();
String resultOfOriginalMethod = fooSpy.bar("42");
assertThat(TestHelper.getLastRecordedStateForVariable("resultOfMockedMethod"), equalTo("spy"));
assertThat(TestHelper.getLastRecordedStateForVariable("resultOfOriginalMethod"), equalTo("bar42"));
assertEquals("spy", resultOfMockedMethod);
assertEquals("bar42", resultOfOriginalMethod);
verify(fooSpy, times(1)).bar();
verify(fooSpy, times(1)).bar("42");
}
@Test
public void spyInAContainer() throws Exception {
Foo foo = new FooImpl();
Foo fooSpy = spy(foo);
MockHolder<Foo> holder = new MockHolder<>(fooSpy);
when(holder.t.bar()).thenReturn("spy");
String resultOfMockedMethod = fooSpy.bar();
String resultOfOriginalMethod = fooSpy.bar("42");
assertThat(TestHelper.getLastRecordedStateForVariable("resultOfMockedMethod"), equalTo("spy"));
assertThat(TestHelper.getLastRecordedStateForVariable("resultOfOriginalMethod"), equalTo("bar42"));
assertEquals("spy", resultOfMockedMethod);
assertEquals("bar42", resultOfOriginalMethod);
verify(fooSpy, times(1)).bar();
verify(fooSpy, times(1)).bar("42");
verify(holder.t, times(1)).bar();
verify(holder.t, times(1)).bar("42");
}
public static class MockHolder<T> {
final T t;
MockHolder(T t) {
this.t = t;
}
@Override
public String toString() {
return t != null ? t.toString() : "(null)";
}
}
static interface Foo {
String bar();
String bar(String s);
}
static class FooImpl implements Foo {
@Override
public String bar() {
return "bar";
}
@Override
public String bar(String s) {
return "bar" + s;
}
}
private String anyString() {
return "42";
}
}