mardi 27 octobre 2015

How is withCapture and withInstanceOf working

When writing tests with JMockit, one can use withCapture() or withInstanceOf(). As an example I want to test the following class:

public class FooProvider {
    public void save(Resource resource, FooList listToSave) {
        // ...
    }
};

If that class is mocked and its save() method is called from the class-under-test, say Bar, we could test, that Bar creates a proper list and calls save():

@Test
public void bar_calls_save_of_FooProvider() {
    // arrange and act
    new Verifications() {{
        FooList fooList;
        fooProvider.save(withInstanceOf(Resource.class), fooList = withCapture());
        assertEquals(42, fooList.size());
    }};
}

When writing this, all works fine and my test succeeds. My question is: How is withCapture() and withInstanceOf working? For sure, I can look in the source code. I'm asking that with the background of moving out the calls like this:

foo.bar(baz());
// is the same as:
Baz b = baz();
foo.bar(b);

That two examples produces the same results, because the compiler do that with every expression used as function argument. But why can I not do this with JMockit? By writing the verification line above into the following, the test is not working anymore:

Resource res = withInstanceOf(Resource.class);
fooProvider.save(res, fooList = withCapture());

I do not asking that to do so in "production" code. It's a matter of interest. Java arguments are evaluated left-to-right and I thought this doesn't have to be different - but it is.

Aucun commentaire:

Enregistrer un commentaire