0

For the life of me, I can't seem to figure out how to prevent the method I'm testing from calling a method in another class.

Here is my test class:

@ExtendWith(MockitoExtension.class)
class QueryHandlerTest {

    @InjectMocks
    QueryHandler queryHandler;

    @Mock
    ResponseBuilder responseBuilder;

    @BeforeEach
    void setUp() {
        MockitoAnnotations.openMocks(this);
    }

    @Test
    void TC5() {
        doThrow(AddMessageResponseException.class).when(responseBuilder).addMessageResponse(isA(Boolean.class), isA(Boolean.class));
        assertThrows(AddMessageResponseException.class, ()-> queryHandler.addMessage("Hello",true));
    }
}

Here is the method that I'm testing:

public void addMessage(String message, boolean lengthExceedsLimit) {
    boolean messageAdded;

    if (checkIfJarExists()) {
        if (!lengthExceedsLimit) {
            // attempt to add the message to the jar
            messageAdded = addMessageQuery(new Message(event.getMessageAuthor().getIdAsString(), message));
        } else {
            messageAdded = false;
        }
    } else {
        messageAdded = false;
    }

    responseBuilder.addMessageResponse(messageAdded, lengthExceedsLimit);

    if (messageAdded) {
        // check to see if the jar's message limit has been reached; if so, perform opening ceremony
        if (checkMessageLimit()) {
            responseBuilder.performOpeningEvent(currentJar);
            deleteJarQuery(this.serverId);
        }
    }
}

And here is the method that it's calling:

public void addMessageResponse(boolean messageAdded, boolean lengthExceedsLimit){

    if (lengthExceedsLimit) {

        event.getChannel().sendMessage("I'm sorry, your message is too long. Please limit your message " +
                "to 250 characters or less.");

    } else if(messageAdded){

        String nickname = getNickname();
        event.getChannel().sendMessage("Thanks, " + nickname + "! Your message has " +
                "been added to the jar!");

    } else {

        event.getChannel().sendMessage("Sorry, it looks like a jar has not been set up for your server. " +
                "If you're a server admin, you can create a jar! " +
                "Please use '!tiko help' to see a list of my commands.");

    }
}

When I run the test, I get this output:

org.opentest4j.AssertionFailedError: Unexpected exception type thrown, 
Expected :class com.tikoJar.exceptions.AddMessageResponseException
Actual   :class java.lang.NullPointerException
<Click to see difference>

...

Caused by: java.lang.NullPointerException: Cannot invoke "org.javacord.api.entity.channel.TextChannel.sendMessage(String)" because the return value of "org.javacord.api.event.message.MessageCreateEvent.getChannel()" is null
    at com.tikoJar.DTO.ResponseBuilder.addMessageResponse(ResponseBuilder.java:35)
    at com.tikoJar.DTO.QueryHandler.addMessage(QueryHandler.java:74)
    at com.tikoJar.DTO.QueryHandlerTest.lambda$TC5$0(QueryHandlerTest.java:68)
    at org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:53)
    ... 73 more

As you can see, the method I'm testing is calling and running the addMessageResponse() method in the ResponseBuilder class, even though I specified in my test that a custom exception should be thrown when attempting to call that method.

I've also tried specifying:

doNothing().when(responseBuilder).addMessageResponse(isA(Boolean.class), isA(Boolean.class));

... but the method still gets called and run. What can I do here?

Lesiak
  • 22,088
  • 2
  • 41
  • 65
  • 2 ideas: 1. You are not using your mock. Show us initialization of responseBuilder field in class under test. 2. Maybe `ResponseBuilder` is final? On top of that you initialize your mocks twice - remove openMocks call. – Lesiak Nov 27 '22 at 20:03
  • Where do you initialize the mock builder in your SUT? I assume the solution is once again [Why is my class not calling my mocked methods in unit test?](https://stackoverflow.com/q/74027324/112968) – knittl Nov 28 '22 at 18:14

0 Answers0