4

Is it possible to test the values of an instance passed as an argument to a method that is void using Mockito?

public String foo() {
    Object o = new ObjectX();
    o.setField("hi");
    someDao.boo(o);
    return "response";
}

boo is void and I want to test that foo sets the field to "hi"

Oscar
  • 1,357
  • 2
  • 17
  • 24
  • 1
    Clarify your question. Show code. – JB Nizet Aug 25 '14 at 16:36
  • 1
    Maybe with an `ArgumentCaptor` when verifying the call. – bric3 Aug 25 '14 at 17:18
  • Since `o` is declared to be an `Object`, it won't have access to the method `setField()`, which I presume lives in `ObjectX`. – Makoto Aug 25 '14 at 19:06
  • I agree with @Brice. [Use an ArgumentCaptor as explained in this post](http://stackoverflow.com/questions/12295891/how-to-use-argumentcaptor-for-stubbing). No point posting a duplicate answer here. – Brad Aug 25 '14 at 19:56

2 Answers2

9

Perhaps you would want to use doNothing method.

@Mock
SomeDao someDao;

@Captor
ArgumentCaptor<ObjectX> captor;

@Test
void test() {
    doNothing().when(someDao).boo(captor.capture());
    foo();
    assertEquals("hi", captor.getValue().getField());
}
Marc Bannout
  • 388
  • 4
  • 15
-1

Updated this is what JB in my comments is suggesting.

@RunWith(MockitoJUnitRunner.class)
public class BarTest
{
    @Mock
    private SomeDao someDao;
    @InjectMocks
    private Bar     bar;

    @Before
    public void initMocks()
    {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testFoo()
    {
        Mockito.doAnswer(new Answer<Object>()
        {
            @Override
            public Object answer(InvocationOnMock invocation) throws Throwable
            {
                ObjectX x = (ObjectX) invocation.getArguments()[0];
                Assert.assertEquals("hi", x.getField());
                return null;
            }
        }).when(someDao).boo(Mockito.any(ObjectX.class));
        Assert.assertEquals("response", bar.foo());
    }
}

This below is my first answer and correct in its own way. No it's not possible with Mockito, since ObjectX is a new Object within the void method, to accomplish this with Mockito then you would have to pass ObjectX in as an argument to the method foo(). You might want to look into Powermock if your code can't be changed.

public String foo(ObjectX objectX) {
    Object o = objectX;
    o.setField("hi");
    someDao.boo(o);
    return "response";
}

Test case

@Test
public void testFoo()
{
    ObjectX mock = Mockito.mock(ObjectX.class);
    Assert.assertEquals("response", foo(mock));
    Mockito.verify(mock, Mockito.times(1)).setField(Mockito.eq("hi"));
}
ndrone
  • 3,524
  • 2
  • 23
  • 37