gpt4 book ai didi

java - Mockito doThrow on void method with null argument not throw exception : What am I doing wrong?

转载 作者:行者123 更新时间:2023-11-30 11:02:27 24 4
gpt4 key购买 nike

我不确定我是发现了错误还是只是做错了。我试图在调用方法时模拟抛出异常(通常相对容易),除了方法是 void 返回类型,以及要传入的对象(为什么抛出错误) 为 null。这样可以通过isNull()类型进行编译,但是还是不报错。

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();
}
}
}

相关maven依赖:

<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>

编辑

我添加了精简的真实代码。今天早上我更多地研究了代码,发现我错误地使用了 Mockito 的 reset()。我认为它会将模拟重置为其未验证状态,但它也会删除 doThrow() stub 。我不得不按如下方式更改初始化方法:

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

@BeforeMethod
public void setUpThrows() {
doThrow(new IllegalArgumentException()).when(messageContainer).setupMessageListener(
isNull(MessageListener.class));
doThrow(new IllegalArgumentException()).when(messageContainer).setupMessageListener(
isNull(SessionAwareMessageListener.class));
}

最佳答案

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

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

关于java - Mockito doThrow on void method with null argument not throw exception : What am I doing wrong?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30767556/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com