Stubbing void methods so that they throw exceptions

In this recipe, we will stub a void method that doesn't return a value, so it throws an exception.

Getting ready

For this recipe, our system under test will be a PersonProcessor class that, for simplicity, does only one thing: it delegates the process of saving person to the PersonSaver class. As shown in the following code, in case of success, true is returned; otherwise, false is returned:

public class PersonProcessor {

    private final PersonSaver personSaver;

    public PersonProcessor(PersonSaver personSaver) {
        this.personSaver = personSaver;
    }

    public boolean process(Person person) {
        try {
            personSaver.savePerson(person);
            return true;
        } catch (FailedToSavedPersonDataException e) {
            System.err.printf("Exception occurred while trying save person data [%s]%n", e);
            return false;
        }
    }

}

How to do it...

If you want your void method to throw an exception upon calling, you need to perform the following steps:

  1. Explicitly tell Mockito that the void method should throw an exception. For the BDD approach, call BDDMockito.willThrow(exception).given(mock).methodToStub(), or in the standard way, call Mockito.doThrow(exception).when(mock).methodToStub().
  2. Regardless of the chosen approach in the given(...) or when(...) method, you have to provide the mock object (and not the method call in the case of methods that return values).
  3. Remember that the last passed value during the stubbing will be returned for each stubbed method call. In other words, say that you stub the mock as follows:
    willThrow(new Exception1()).willThrow(new Exception2()).given(personSaver).savePerson(smith);

    Then, regardless of the number of personSaver.savePerson(...) method executions, first Exception1 will be thrown, and then you will always have Exception2 thrown (until it is stubbed again).

Let's check the JUnit test. See Chapter 1, Getting Started with Mockito, for the TestNG configuration (remember that I'm using BDDMockito.given(...) and AssertJ's BDDAssertions.then(...) static methods. Check out Chapter 7, Verifying Behavior with Object Matchers, for more details on how to work with AssertJ or how to do the same with Hamcrest's assertThat(...)):

@RunWith(MockitoJUnitRunner.class)
public class PersonProcessorTest {

    @Mock PersonSaver personSaver;

    @InjectMocks PersonProcessor systemUnderTest;

    @Test
    public void should_fail_to_save_person_data_when_exception_occurs() {
        // given
        willThrow(FailedToSavedPersonDataException.class).given(personSaver).savePerson(any(Person.class));

        // when
        boolean updateSuccessful = systemUnderTest.process(new Person());

        // then
        then(updateSuccessful).isFalse();
    }

}

How it works...

Please refer to the Stubbing void methods recipe for more information on the Mockito internals that are related to stubbing void methods.

What's worth mentioning is that the answers that take part in the Mockito internal delegation process are either ThrowsExceptionClass or ThrowsException answers.

See also

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.168.203