-1

I'm testing a class TestObject. In this class there is a void returning function stageOne(String) which I want to test. At the end of stageOne there is a call to another void returning function, stageTwo(String). I want to fake the response from stageTwo so that stageTwo is never actually called. To pass the test TestObject needs to call stageTwo exactly once.

I've tried a variety of things using when...thenReturn but just can't get it to work. Below is my current best guess.

class TestClass {
    private TestObject testObject;

    @Before
    public static void setUp() {
        testObject = new TestObject();
    }

    @Test
    public void test1() {
        when(testObject.stageTwo(any(String.class))).thenReturn(Void);
        testObject.stageOne("Test data");
        verify(testObject, times(1)).stageTwo(any(String.class));
    }    
}

I'm using IntelliJ and have been able to do other tests, I just can't get the when...then constructs to work at all. At the moment with the above example IntelliJ is suggesting that I make it into a local variable OngoingStubbing<Void> voidOngoingStubbing and then it says that that's wrong too.

I have also tried the line

doNothing().when(testObject.stageTwo(any(String.class)));

but that doesn't work either. intelliJ underlines the contents of when() with the same message as before.

EDIT: TestObject structure below:

public class TestObject {

  public void stageOne(String str) {
    String str2 = ...
    // do stuff
    stageTwo(str2) // don't proceed with this method, but verify that it was called
  }

  public void stageTwo(String str) {
    // do stuff which I don't want to do in this test
    // e.g. calls to external services and other complexities
  }

}
Chro
  • 1,003
  • 2
  • 15
  • 27
  • you will have to create mock object first, I think PowerMock. – Vishrant Dec 22 '15 at 13:56
  • First up, you want to use a Mockito spy. Secondly, you've got the parentheses in the wrong place. You should write `doNothing().when(testObject).stageTwo(anyString());` assuming that `testObject` is a spy. – Dawood ibn Kareem Dec 22 '15 at 17:46

1 Answers1

1

You could use a partial mock, like the example here. Make sure you create the object as a mock first though.

TestObject testObject = mock(TestObject.class);
doNothing().when(testObject.stageTwo(anyString()));
when(testObject.stageOne(anyString())).thenCallRealMethod();

If it's worth splitting up your code into two methods, it may be better to think about refactoring your code. For instance, if it's reasonable for code to call your object and only run the first method, then remove the call to stageTwo from the first method and force calling code to call both stageOne and stageTwo. Or, alternatively, get stageOne to return it's string, and write a third method to call all stages:

public void allStages(String str) {
    String str2 = stageOne(str);
    stageTwo(str2);
}

This nicely breaks up your methods, and allows you to test them individually. The way you have it setup at the moment there is too much coupling between the two methods, and so if you really want them to be separate, you should consider something like this.

Community
  • 1
  • 1
AndyN
  • 2,075
  • 16
  • 25