package org.testory; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; import static org.junit.Assert.fail; import static org.testory.Testory.given; import static org.testory.Testory.mock; import static org.testory.Testory.spy; import static org.testory.Testory.thenCalled; import static org.testory.Testory.willReturn; import static org.testory.Testory.willSpy; import static org.testory.testing.Fakes.newObject; import static org.testory.testing.Fakes.newThrowable; import org.junit.Before; import org.junit.Test; import org.testory.proxy.Invocation; import org.testory.proxy.InvocationMatcher; public class TestSpying { private Mockable mock, spy, real, otherMock; private Object object; private Throwable throwable; @Before public void before() { mock = mock(Mockable.class); otherMock = mock(Mockable.class); real = new Mockable(); object = newObject("object"); throwable = newThrowable("throwable"); } @Test public void returns_from_real_object_method() { spy = spy(real); assertEquals(object, spy.doReturn(object)); given(willSpy(real), onInstance(mock)); assertEquals(object, mock.doReturn(object)); } @Test public void throws_from_real_object_method() throws Throwable { spy = spy(real); try { spy.doThrow(throwable); fail(); } catch (Throwable e) { assertSame(e, throwable); } given(willSpy(real), onInstance(mock)); try { mock.doThrow(throwable); fail(); } catch (Throwable e) { assertSame(e, throwable); } } @Test public void can_be_stubbed() { spy = spy(real); given(willReturn(object), onInstance(mock)); assertSame(object, mock.doReturn(null)); given(willSpy(real), onInstance(mock)); given(willReturn(object), onInstance(mock)); assertSame(object, mock.doReturn(null)); } @Test public void can_be_verified() { spy = spy(real); spy.doReturn(object); thenCalled(onInstance(spy)); given(willSpy(real), onInstance(mock)); mock.doReturn(object); thenCalled(onInstance(mock)); } @Test public void can_spy_another_mock() { spy = spy(otherMock); given(willReturn(object), onInstance(otherMock)); assertEquals(object, spy.doReturn(null)); given(willSpy(otherMock), onInstance(mock)); given(willReturn(object), onInstance(otherMock)); assertEquals(object, mock.doReturn(null)); } @Test public void cannot_spy_null() { try { willSpy(null); fail(); } catch (TestoryException e) {} try { spy(null); fail(); } catch (TestoryException e) {} } private static InvocationMatcher onInstance(final Object mock) { return new InvocationMatcher() { public boolean matches(Invocation invocation) { return invocation.instance == mock; } }; } private static class Mockable { Object doReturn(Object o) { return o; } Object doThrow(Throwable t) throws Throwable { throw t; } } }