Java 检查是否在EasyMock上调用了方法
使用EasyMock 3.2。为了对UI进行单元测试,我必须模拟一些依赖项。其中之一是Java 检查是否在EasyMock上调用了方法,java,unit-testing,mocking,easymock,Java,Unit Testing,Mocking,Easymock,使用EasyMock 3.2。为了对UI进行单元测试,我必须模拟一些依赖项。其中之一是页面。UI测试的基类如下所示: abstract class AbstractUiTest { @Before public function setUpUiDependencies() { Page page = createNiceMock(Page.class); Ui.setCurrentPage(page); } } 大多数时候,我没有明确地使
页面
。UI测试的基类如下所示:
abstract class AbstractUiTest {
@Before
public function setUpUiDependencies() {
Page page = createNiceMock(Page.class);
Ui.setCurrentPage(page);
}
}
大多数时候,我没有明确地使用页面,只是在Ui调用getPage().setTitle(“sth”)
等时不抛出NullPointerException
但是,在一些测试中,我想明确检查页面是否出现了问题,例如:
public class SomeTest extends AbstractUiTest {
@Test
public void testNotification() {
// do something with UI that should cause notification
assertNotificationHasBeenShown();
}
private void assertNotificationHasBeenShown() {
Page page = Ui.getCurrentPage(); // this is my nice mock
// HERE: verify somehow, that page.showNotification() has been called
}
}
如何实现断言方法?我真的很想实现它,而不需要记录页面的行为,重放和验证它。我的问题有点复杂,但你应该明白这一点。编辑:我认为这可能不是真的需要,因为简单地使用replay和verify应该检查预期的方法是否实际被调用。但你说过你想在不重播和验证的情况下做这件事。你能解释一下你为什么有这个要求吗 我认为您可以使用
和answer
以及IAnswer
。您没有提到page.showNotification()
的返回值是什么。假设它返回字符串,则可以执行以下操作:
import static org.easymock.EasyMock.expect;
import static org.junit.Assert.assertTrue;
import java.util.concurrent.atomic.AtomicBoolean;
import org.easymock.IAnswer;
import org.junit.Ignore;
import org.junit.Test;
public class SomeTest extends AbstractUiTest {
@Test
public void shouldCallShowNotification() {
final AtomicBoolean showNotificationCalled = new AtomicBoolean();
expect(page.showNotification()).andAnswer(new IAnswer<String>() {
@Override
public String answer() {
showNotificationCalled.set(true);
return "";
}
});
replay(page);
Ui.getCurrentPage();
verify(page);
assertTrue("showNotification not called", showNotificationCalled.get());
}
}
导入静态org.easymock.easymock.expect;
导入静态org.junit.Assert.assertTrue;
导入java.util.concurrent.AtomicBoolean;
导入org.easymock.IAnswer;
导入org.junit.Ignore;
导入org.junit.Test;
公共类SomeTest扩展了AbstractUiTest{
@试验
public void shouldCallShowNotification()应为空{
final AtomicBoolean showNotificationCalled=新AtomicBoolean();
expect(page.showNotification()).andAnswer(new IAnswer()){
@凌驾
公共字符串应答(){
showNotificationCalled.set(true);
返回“”;
}
});
重播(第页);
Ui.getCurrentPage();
验证(第页);
assertTrue(“未调用showNotification”,showNotificationCalled.get());
}
}
如果showNotification返回void,我相信您需要执行以下操作:
import static org.easymock.EasyMock.expectLastCall;
import static org.junit.Assert.assertTrue;
import java.util.concurrent.atomic.AtomicBoolean;
import org.easymock.IAnswer;
import org.junit.Ignore;
import org.junit.Test;
public class SomeTest extends AbstractUiTest {
@Test
public void shouldCallShowNotification() {
final AtomicBoolean showNotificationCalled = new AtomicBoolean();
page.showNotification();
expectLastCall().andAnswer(new IAnswer<Void>() {
@Override
public Void answer() {
showNotificationCalled.set(true);
return null;
}
});
replay(page);
Ui.getCurrentPage();
verify(page);
assertTrue("showNotification not called", showNotificationCalled.get());
}
}
导入静态org.easymock.easymock.expectLastCall;
导入静态org.junit.Assert.assertTrue;
导入java.util.concurrent.AtomicBoolean;
导入org.easymock.IAnswer;
导入org.junit.Ignore;
导入org.junit.Test;
公共类SomeTest扩展了AbstractUiTest{
@试验
public void shouldCallShowNotification()应为空{
final AtomicBoolean showNotificationCalled=新AtomicBoolean();
page.showNotification();
expectLastCall().andAnswer(新IAnswer()){
@凌驾
公开答案(){
showNotificationCalled.set(true);
返回null;
}
});
重播(第页);
Ui.getCurrentPage();
验证(第页);
assertTrue(“未调用showNotification”,showNotificationCalled.get());
}
}
注意:我使用了AtomicBoolean
来记录是否调用了该方法。您还可以使用单个元素的布尔数组,或者您自己的可变对象。我使用AtomicBoolean
不是因为它的并发属性,而是因为它是一个方便的可变布尔对象,已经存在于Java标准库中
我为验证调用了一个方法而做的另一件事是根本不使用mock,而是创建一个Page实例作为匿名内部类,并重写showNotification方法,并记录调用发生的位置。在不关心page发生了什么的测试中使用nice模拟,在想要测试显式内容的测试中使用expect、verify等。也就是说,在设置方法中有两个变量:nicePage(用作存根)和mockPage(用作模拟)您希望验证是否已调用模拟上的方法,但随后声明不希望使用
expect()
、replay()
或verify()
。这些方法正是你想要实现的目标,你为什么不使用它们呢?你明白吗?用一个很好的模拟,你只需要期待你想要验证的电话?您不需要一大堆不希望验证的期望值。我不喜欢expect()
,replay()
,verify()
解决方案的原因是,在每个需要通知的测试中都会重复此代码,这将引入不必要的混乱(澄清一下,在我的真实代码中有三到四件事情需要期待和重放)。即使我创建了一些helper方法,我也必须记住在验证通知存在性的测试开始时调用它们。这就是为什么我要求更好的解决方案。