使用EasyMock 3.2。为了对UI进行单元测试,我必须模拟一些依赖项。其中一个是Page
。 UI测试的基类如下所示:
abstract class AbstractUiTest {
@Before
public function setUpUiDependencies() {
Page page = createNiceMock(Page.class);
Ui.setCurrentPage(page);
}
}
大部分时间我都没有使用页面显式,只是在那里不会抛出NullPointerException,例如Ui打电话给getPage().setTitle("sth")
等。
然而,在一些测试中,我想明确检查页面是否发生了某些事情,例如:
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
}
}
如何实现断言方法?我真的想要实现它而不记录页面的行为,重放和验证它。我的问题有点复杂,但你应该明白这一点。
答案 0 :(得分:2)
编辑:我认为这可能并不是真的需要,因为只需使用重播和验证就应该检查实际调用了预期的方法。但是你说你想在不重播和验证的情况下这样做。你能解释一下为什么你有这个要求吗?
我认为您可以使用andAnswer
和IAnswer
。你没有提到page.showNotification()
的返回值是什么。假设它返回一个String,你可以这样做:
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());
}
}
如果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());
}
}
注意:我已使用AtomicBoolean
来记录方法是否被调用。您还可以使用单个元素的布尔数组或您自己的可变对象。我使用AtomicBoolean
不是因为它的并发属性,而只是因为它是一个方便的可变布尔对象,已经存在于Java标准库中。
我验证调用方法的另一件事是根本不使用mock,而是创建Page的实例作为匿名内部类并覆盖showNotification方法,并记录某个地方打电话。
答案 1 :(得分:0)
在测试中使用一个漂亮的模拟,你不关心页面发生了什么,在那些你想要测试一些东西的测试中使用普通的模拟 - 并使用expect,验证等等。在你的setup方法中有两个变量:nicePage(充当存根)和mockPage(充当模拟)