Obaid Maroof
Obaid Maroof

Reputation: 1579

Understanding semantics behind Mockito verify

I have problem understanding the semantics behind the following piece of code.

@Test
public void TestAbc() throws AbcException {
    // method to test
    object.handle();

    // assertions
    verify(someThing).someMethod();
    verify(problemObject).problemMethod();
}

Where the definition for the handle method is as follows:

public void handle() {
    try {
        someThing.someMethod();
        // throws AbcException
        problemObject.problemMethod();
    }
    catch (AbcException e) {
        LOGGER.error(e.getMessage());
    }
}

Now in my test I am doing throws AbcException to keep things syntactically correct but this doesn't really make sense since I am catching the exception within the handle method and is not throwing it further. But the test method translates to "TestAbc throws AbcException" which is not really the case. So my problem is why do I need to add throws AbcException to my test method even its not thrown? Can someone help me understanding this?

Upvotes: 1

Views: 96

Answers (3)

JB Nizet
JB Nizet

Reputation: 691655

throws doesn't mean that a method throws an exception. It means that the method can throw an exception. Since the TestAbc() calls problemMethod(), and this method can throw the checked AbcException, and you're not catching it in the test method, you must declare it to make the compiler happy.

The exception will, at runtime, never be thrown, because Mockito won't throw that exception. But the compiler doesn't know that.

Upvotes: 3

Aasmund Eldhuset
Aasmund Eldhuset

Reputation: 37950

verify(problemObject) returns an instance of a Mockito class that is used to specify what you want to verify. In order to allow for the fluent syntax where you can simply call problemMethod() on this object, the class implements the interface (or extends the class) that problemObject is mocking. Even though problemMethod() in this class simply has the effect of checking whether problemMethod() was called on the mock, the Java compiler doesn't know this and only sees that you're calling a method whose signature says throws AbcException, so you need to handle it.

P.S.: Unless you have other setup code, your mocked problemMethod will not actually throw anything - you need to explicitly set the mock up for that:

when(problemObject.problemMethod()).thenThrow(new AbcException());

Upvotes: 3

benzonico
benzonico

Reputation: 10833

You are forced to add AbcException to the signature of your test because in your assertion you are calling problemMethod which has in its signature throws AbcException. (I suppose AbcException is a checked exception).

Therefore you must either catch or rethrow this exception. verify will return an object of type of the one you feed it with, so for java compiler you are just invoking a method which can throw a checked exception and so you are forced to handle it.

Upvotes: 1

Related Questions