Search code examples
javajmockitside-effects

Simulating side effects of a mocked method


I have a method in a class that causes side effects to the method's parameter:

public void SideEffectsClass {
    public void doSomethingWithSideEffects(List<Object> list) {
        // do something to the list
    }
}

And this class being tested:

public void ClassUnderTest() {
   public List<Object> execute() {
       List<Object> results = new ArrayList<Object>();
       new SideEffectsClass().doSomethingWithSideEffects(results);
       return results;
   }
}

My test method using JMockit:

@Test
public void test() throws Exception
{
    // arrange
    new Expectations()
    {
        SideEffectsClass sideEffects;
        {
            new SideEffectsClass();
            sideEffects.doSomethingWithSideEffects((List<Object>) any);
            // I want to simulate that the List<Object> parameter has changed 
            // (has more elements, less elements, etc. after this method is called
        }
    };

    // act
    ClassUnderTest testClass = new ClassUnderTest();
    List<Object> results = testClass.execute();

    // assert
    Assert.assertEquals(myExpectedResults, results);
}

Solution

  • You can use a Delegate object to change an argument value:

        sideEffects.doSomethingWithSideEffects((List<Object>) any);
        result = new Delegate() {
            void delegate(List<Object> list) { list.add(new Object()); }
        };
    

    If all you need is to verify that the doSomethingWithSideEffects methods was called, then the test could be written more simply as:

    @Test
    public void test(final SideEffectsClass sideEffects)
    {
        List<Object> results = new ClassUnderTest().execute();
    
        assertEquals(myExpectedResults, results);
    
        new Verifications() {{
            sideEffects.doSomethingWithSideEffects((List<Object>) any);
        }};
    }