所以这与this的问题基本相同,但我的动机不同。 我也使用cucumber-jvm而不是ruby版本。
基本上我想在每个EasyMock.expect()
步骤中记录Given
的期望值,然后在处理完所有步骤后我想调用replay()
(由于easymock的工作原理,这是必要的 - 你必须先记录所有的期望,然后明确地开始重播阶段。
使用EasyMock有没有办法做到这一点?是否有其他方法将Record-Replay-Verify模拟与黄瓜整合?
答案 0 :(得分:0)
尝试使用JMockIt。 它有更多可以使用的功能,并且还具有您想要的模拟算法。 申请很简单。
示例:
package jmockit.tutorial.domain;
import java.math.*;
import java.util.*;
import org.apache.commons.mail.*;
import static jmockit.tutorial.persistence.Database.*;
public final class MyBusinessService
{
public void doBusinessOperationXyz(EntityX data) throws EmailException
{
List<EntityX> items =
(1) find("select item from EntityX item where item.someProperty = ?1", data.getSomeProperty());
// Compute or obtain from another service a total value for the new persistent entity:
BigDecimal total = ...
data.setTotal(total);
(2) persist(data);
sendNotificationEmail(data, items);
}
private void sendNotificationEmail(EntityX data, List<EntityX> items) throws EmailException
{
Email email = new SimpleEmail();
email.setSubject("Notification about processing of ...");
(3) email.addTo(data.getCustomerEmail());
// Other e-mail parameters, such as the host name of the mail server, have defaults defined
// through external configuration.
String message = buildNotificationMessage(items);
email.setMsg(message);
(4) email.send();
}
private String buildNotificationMessage(List<EntityX> items) { ... }
}
现在使用Expectations API
首先,让我们使用JMockit Expectations API。
package jmockit.tutorial.domain;
import org.apache.commons.mail。; import jmockit.tutorial.persistence。;
import org.junit。; import mockit。;
public final class MyBusinessService_ExpectationsAPI_Test
{
@Mocked(stubOutClassInitialization = true) final Database unused = null;
@Mocked SimpleEmail email;
@Test
public void doBusinessOperationXyz() throws Exception
{
final EntityX data = new EntityX(5, "abc", "abc@xpta.net");
// Recorded strictly, so matching invocations must be replayed in the same order:
new Expectations() {{
(1) Database.find(withSubstring("select"), any);
result = new EntityX(1, "AX5", "someone@somewhere.com");
(2) Database.persist(data);
}};
// Recorded non-strictly, so matching invocations can be replayed in any order:
new NonStrictExpectations() {{
(4) email.send(); times = 1; // a non-strict invocation requires a constraint if expected
}};
new MyBusinessService().doBusinessOperationXyz(data);
}
@Test(expected = EmailException.class)
public void doBusinessOperationXyzWithInvalidEmailAddress() throws Exception
{
new NonStrictExpectations() {{
(3) email.addTo((String) withNotNull()); result = new EmailException();
// If the e-mail address is invalid, sending the message should not be attempted:
email.send(); times = 0;
}};
EntityX data = new EntityX(5, "abc", "someone@somewhere.com");
new MyBusinessService().doBusinessOperationXyz(data);
}
}
使用Verifications API
package jmockit.tutorial.domain;
import org.apache.commons.mail.*;
import jmockit.tutorial.persistence.*;
import org.junit.*;
import mockit.*;
public final class MyBusinessService_VerificationsAPI_Test
{
@Tested MyBusinessService service; // instantiated automatically
@Mocked(stubOutClassInitialization = true) Database onlyStatics;
@Capturing Email email; // concrete subclass mocked on demand, when loaded
final EntityX data = new EntityX(5, "abc", "someone@somewhere.com");
@Test
public void doBusinessOperationXyzPersistsData() throws Exception
{
// No expectations recorded in this case.
service.doBusinessOperationXyz(data);
(2) new Verifications() {{ Database.persist(data); }};
}
@Test
public void doBusinessOperationXyzFindsItemsAndSendsNotificationEmail() throws Exception
{
// Invocations that produce a result are recorded, but only those we care about.
new NonStrictExpectations() {{
(1) Database.find(withSubstring("select"), (Object[]) null);
result = new EntityX(1, "AX5", "someone@somewhere.com");
}};
service.doBusinessOperationXyz(data);
new VerificationsInOrder() {{
(3) email.addTo(data.getCustomerEmail());
(4) email.send();
}};
}
}
我希望这可以回答你的问题。