Mockito doThrow在void方法上使用null参数而不是抛出异常:我做错了什么?

时间:2015-06-10 21:23:12

标签: java mockito

我不确定我是否发现了一个错误,或者我是否做错了。我试图在调用方法(通常相对容易)时使用模拟抛出异常,除了方法是void返回类型,并且要传入的对象(为什么抛出错误)是{ {1}}。这可以通过null输入来编译,但仍然不会抛出错误。

isNull()

相关的maven依赖项:

package some.example;

import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.MockitoAnnotations.initMocks;

import javax.jms.Message;
import javax.jms.MessageListener;

import org.mockito.Mock;
import org.springframework.jms.listener.AbstractMessageListenerContainer;
import org.springframework.jms.listener.SessionAwareMessageListener;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class TestClass {
    @Mock
    private AbstractMessageListenerContainer messageContainer;

    @BeforeClass
    public void setUpMocks() {
        initMocks(this);

        doThrow(new IllegalArgumentException()).when(messageContainer).setupMessageListener(
                isNull(MessageListener.class));
        doThrow(new IllegalArgumentException()).when(messageContainer).setupMessageListener(
                isNull(SessionAwareMessageListener.class));
    }

    @AfterMethod
    public void resetMocks() {
        reset(messageContainer);
    }

    @Test(expectedExceptions = { IllegalArgumentException.class })
    public void testSetUpQueueConsumerWithNullMessageListener() throws Exception {
        final MessageListener messageListener = null;
        try (final QueueConsumer consumer = new QueueConsumer(messageContainer, messageListener)) {
        } finally {
            verify(messageContainer).setupMessageListener(messageListener);
        }
    }

    @Test(expectedExceptions = { IllegalArgumentException.class })
    public void testSetUpQueueConsumerWithNullSessionAwareMessageListener() throws Exception {
        final SessionAwareMessageListener<Message> messageListener = null;
        try (final QueueConsumer consumer = new QueueConsumer(messageContainer, messageListener)) {
        } finally {
            verify(messageContainer).setupMessageListener(messageListener);
        }
    }

    public class QueueConsumer implements AutoCloseable {
        private final AbstractMessageListenerContainer messageContainer;

        QueueConsumer(final AbstractMessageListenerContainer messageContainer,
                final SessionAwareMessageListener<? extends Message> messageListener) {
            this(messageContainer);
            this.messageContainer.setupMessageListener(messageListener);
        }

        QueueConsumer(final AbstractMessageListenerContainer messageContainer, final MessageListener messageListener) {
            this(messageContainer);
            this.messageContainer.setupMessageListener(messageListener);
        }

        private QueueConsumer(final AbstractMessageListenerContainer messageContainer) {
            if (messageContainer == null) {
                throw new IllegalArgumentException("MessageListenerContainer cannot be null");
            }
            this.messageContainer = messageContainer;
        }

        public void stop() {
            messageContainer.stop();
        }

        @Override
        public void close() throws Exception {
            stop();
        }
    }
}

修改

我添加了精简的实际代码。今天早上我玩了更多的代码,发现我错误地使用了Mockito的<dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>6.8.21</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>2.0.8-beta</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> <version>${org.springframework.version}</version> </dependency> 。我认为它会将模拟重置为未经验证的状态,但它也会删除reset()存根。我必须按如下方式更改初始化方法:

doThrow()

1 个答案:

答案 0 :(得分:1)

在评论和编辑中已解决:请注意reset方法完全重置模拟 ,包括存根和交互(后者用于验证)。

作为warned in the Mockito documentationreset通常是您测试中的一个不好的标志:如果它位于测试方法的中间,通常该方法应该分成多个较小的测试,如果它它来自@After@AfterMethod,这意味着您的测试设置会在测试之间造成污染。将您的模拟保存在实例字段中,而不是静态字段中,在@Before(JUnit)或@BeforeMethod(TestNG)方法中初始化,以确保在测试类中的每次测试之前完全覆盖它们。