vendredi 21 août 2015

Mockito: how to stub void methods to run some code when called

I want to stub a repository class to test another class (Holder class) that has a repository. The repository interface supports CRUD operations, and has many methods, but my unit test on the Holder class only needs to call two of them. The repository interface:

public interface IRepo {
    public void remove(String... sarr);

    public void add(String... sarr);

    //Lots of other methods I don't need now
}

I want to create a repository mock that can store instances, define logic for add and remove only, and also provide a means of checking what is stored on it after calling add and remove.

If I do:

IRepo repoMock = mock(IRepo.class);

Then I have a dumb object that does nothing on each method. That's OK, now I just need to define behaviour for add and remove.

I could create a Set<String> and stub only those two methods to work on the set. Then I'd instantiate a Holder that has an IRepo, inject the partially stubbed mock, and after exercising the holder, check the set to verify it contains what it should.

I've managed to partially stub a void method like remove using the deprecated method stubVoid:

Set<String> mySet = new HashSet<>();
stubVoid(repoMock).toAnswer(new Answer<Void>() {

    @Override
    public Void answer(InvocationOnMock invocation) throws Throwable {
        Object[] args = invocation.getArguments();
        String[] stringsToDelete = (String[]) args[0];
        mySet.removeAll(Arrays.asList(stringsToDelete));
        return null;
    }
}).on().remove(Matchers.<String>anyVararg());

But is deprecated, and it is not much better than creating a partial implementation for IRepo. Is there a better way?

NOTE: Java 7 answers only please, this should run in Android.

Aucun commentaire:

Enregistrer un commentaire