4

I am new to Mockito and I was wondering how I could stub a get/set pair.

For example

public interface Order {
     public short getStatus();
     public void setStatus(short status);
}

How can I make them behave properly:

if somewhere in a test I invoke setStatus(4); I would like getStatus() to return 4. How can this be done?

Sam Holder
  • 32,535
  • 13
  • 101
  • 181
The Schwartz
  • 757
  • 1
  • 8
  • 13

2 Answers2

5

Are you stubbing or mocking?

The difference is whether you are verifying behaviour or providing data for a test. You say:

if somewhere in a test I invoke setStatus(4); I would like getStatus() to return 4.

this implies both at the same time. You either want to verify that setStatus() was called with an argument 4.

verify(mockObject).setStatus(4);

or you want to set your mock object to return 4 when getStatus() is called.

when(mockObject.getStatus()).thenReturn(4);

Mockito has some tutorials which explain how to use it for each situation. I suspect you could do both in your test (but have not checked) but this would be a smell to me, as you should ideally only be checking mocking a single thing in your test, everything else should be stubbed. But, as ever, context is everything and so it may be that you need to stub one part of your object so you can verify the behaviour of another part, in which case it would be fine.

Follow the AAA syntax and arrange your test (ie do the setup and have the when clause) then act (ie call the method on the object under test) then do your asserts (ie have your verify statements)

EDIT

it seems that in the newer versions (1.8+) of mockito it may be possible to do what you want, although it is not recommended. You can use a Spy to create a partial mock of an object. In this case you should be able to create a Spy of your actual object, leave the getStatus() and setStatus() methods un-stubbed (so they are actually called and used) and just stub out the other methods (or just verify they were called presumably). You can read about it in section 13 Spying on real objects on this page.

Community
  • 1
  • 1
Sam Holder
  • 32,535
  • 13
  • 101
  • 181
  • I want to have my mock object to behave with a real get/set functionality. – The Schwartz May 09 '12 at 10:56
  • @TheSchwartz then mockito is not the way to do it. You need to write your own mock object then, or use a different framework which provides the functionality you want. – Sam Holder May 09 '12 at 11:42
  • You're quite right and I've found that the use of verify(mockObject, times(1)).setStatus(4); solves my purpose. Thanks. – The Schwartz May 09 '12 at 12:07
  • Another method could be to use capturing of arguments: [Capturing of arguments](http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html#15), but it seem somewhat an overkill in my situation - Thanks. – The Schwartz May 09 '12 at 12:20
  • @TheSchwartz don't forget to mark the answer as accepted (using the Tick under the voting buttons on the left of the answer) if it solved your issue (just pointing it out as someone will if you don't accept answers eventually) – Sam Holder May 09 '12 at 12:43
  • in `verify(mockObject, times(1)).setStatus(4);` the `times(1)` is redundant as it is the default. but glad you got your issue sorted :) – Sam Holder May 09 '12 at 12:44
  • @TheSchwartz I updated my answer with something that may get you what you originally asked for, however it is not recommended and should be used with caution. – Sam Holder May 10 '12 at 08:27
3

You can set the behavior of the setStatus method so that it updates the behavior of the getStatus method, as follows:

    Mockito.doAnswer(invocation -> {
        short status = invocation.getArgumentAt(0, Short.class);
        Mockito.when(mockOrder.getStatus()).thenReturn(status);
        return null;
    }).when(mockOrder).setStatus(Mockito.anyShort());
amitzko
  • 51
  • 3