在 JUnit 测试中,有没有一种方法可以确保所有断言都已执行?
In a JUnit test, is there a way I can ensure that all assertions have been executed?
我有一个 Producer
和一个 Consumer
。 Producer
同步写入消息。消费者是每秒轮询消息的线程。
我有这样的测试:
@Test
public void shouldConsumeMessageWhenMessageIsProduced() {
final Message expectedMessage = new Message("test");
//consumer will poll every 1 second for a message
consumer.poll((actualMessage) -> {assertThat(actualMessage), is(expectedMessage));
producer.sendSynchronously(expectedMessage);
Thread.sleep(3000);
}
这个测试有效。但是,我无法确保确实调用了断言。
我意识到我可以使用 Mockito,但我也意识到这更像是一个集成测试而不是单元测试。但是 JUnit 中有没有确保所有断言都已执行的方法呢?
请注意,由于断言是在 lambda 中,我不能递增变量或设置标志。
我会根据您的喜好使用您的 lambda 表达式中的 AtomicBoolean
或 MutableBoolean
。有关示例,请参见以下代码:
import static org.junit.Assert.assertTrue;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.lang.mutable.MutableBoolean;
import org.junit.Test;
public class AssertionLambdaTest {
@Test
public void assertExecutedWithAtomicBoolean() {
AtomicBoolean myBoolean = new AtomicBoolean(false);
doStuff(() -> {
assertTrue(true);
myBoolean.set(true);
});
assertTrue(myBoolean.get());
}
@Test
public void assertExecutedWithMutableBoolean() {
MutableBoolean myBoolean = new MutableBoolean(false);
doStuff(() -> {
assertTrue(true);
myBoolean.setValue(true);
});
assertTrue(myBoolean.booleanValue());
}
private void doStuff(Runnable runner) {
runner.run();
}
}
编辑:我刚刚意识到你的问题是“所有断言”。因此,您可以以相同的方式等效地使用 Apache's MutableInt
class or Java's AtomicInteger
,只是递增直到达到正确的数字。
您似乎希望您的测试等到断言被触发,可能有超时。 CountDownLatch
可以完成这项工作:
@Test
public void shouldConsumeMessageWhenMessageIsProduced() {
final Message expectedMessage = new Message("test");
CountDownLatch messageReceived = new CountDownLatch(1);
//consumer will poll every 1 second for a message
consumer.poll(actualMessage -> {
assertThat(actualMessage, is(expectedMessage));
messageReceived.countDown();
}
producer.sendSynchronously(expectedMessage);
//wait until the message is received, but not more than one second
//await returns false if it reaches the timeout
assertTrue(messageReceived.await(1, SECONDS));
}
如果希望consumer中的断言被触发n次,可以更改latch的初始计数:CountDownLatch latch = new CountDownLatch(n);
.
我有一个 Producer
和一个 Consumer
。 Producer
同步写入消息。消费者是每秒轮询消息的线程。
我有这样的测试:
@Test
public void shouldConsumeMessageWhenMessageIsProduced() {
final Message expectedMessage = new Message("test");
//consumer will poll every 1 second for a message
consumer.poll((actualMessage) -> {assertThat(actualMessage), is(expectedMessage));
producer.sendSynchronously(expectedMessage);
Thread.sleep(3000);
}
这个测试有效。但是,我无法确保确实调用了断言。
我意识到我可以使用 Mockito,但我也意识到这更像是一个集成测试而不是单元测试。但是 JUnit 中有没有确保所有断言都已执行的方法呢?
请注意,由于断言是在 lambda 中,我不能递增变量或设置标志。
我会根据您的喜好使用您的 lambda 表达式中的 AtomicBoolean
或 MutableBoolean
。有关示例,请参见以下代码:
import static org.junit.Assert.assertTrue;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.lang.mutable.MutableBoolean;
import org.junit.Test;
public class AssertionLambdaTest {
@Test
public void assertExecutedWithAtomicBoolean() {
AtomicBoolean myBoolean = new AtomicBoolean(false);
doStuff(() -> {
assertTrue(true);
myBoolean.set(true);
});
assertTrue(myBoolean.get());
}
@Test
public void assertExecutedWithMutableBoolean() {
MutableBoolean myBoolean = new MutableBoolean(false);
doStuff(() -> {
assertTrue(true);
myBoolean.setValue(true);
});
assertTrue(myBoolean.booleanValue());
}
private void doStuff(Runnable runner) {
runner.run();
}
}
编辑:我刚刚意识到你的问题是“所有断言”。因此,您可以以相同的方式等效地使用 Apache's MutableInt
class or Java's AtomicInteger
,只是递增直到达到正确的数字。
您似乎希望您的测试等到断言被触发,可能有超时。 CountDownLatch
可以完成这项工作:
@Test
public void shouldConsumeMessageWhenMessageIsProduced() {
final Message expectedMessage = new Message("test");
CountDownLatch messageReceived = new CountDownLatch(1);
//consumer will poll every 1 second for a message
consumer.poll(actualMessage -> {
assertThat(actualMessage, is(expectedMessage));
messageReceived.countDown();
}
producer.sendSynchronously(expectedMessage);
//wait until the message is received, but not more than one second
//await returns false if it reaches the timeout
assertTrue(messageReceived.await(1, SECONDS));
}
如果希望consumer中的断言被触发n次,可以更改latch的初始计数:CountDownLatch latch = new CountDownLatch(n);
.