我想知道如何检查一个方法返回一个封装某个集合的容器,该集合是mock对象返回的多个其他容器的集合。也就是说,它包含各个容器的所有元素。我在其他地方进行了一些测试,检查容器的“工作”(添加/ addAll / etc),所以我知道这有效,但我不确定如何在'createsRoadUsersAccordingToAllAddedCreators'下面进行测试。
我有一个RoadUserCreationDaemon类,我称之为create,根据添加的RoadUserCreator返回RoadUserContainer。简化版本:
public class RoadUserCreationDaemon {
private SimulationManager simulationManager;
private List<RoadUserCreator> roadUserCreators;
public RoadUserCreationDaemon(SimulationManager simulationManager) {
this.simulationManager = simulationManager;
roadUserCreators = new ArrayList<RoadUserCreator>();
}
public void addRoadUserCreator(RoadUserCreator roadUserCreator) {
roadUserCreators.add(roadUserCreator);
}
public RoadUserContainer createRoadUsers() {
RoadUserContainer roadUsers = new RoadUserContainerImpl();
for (RoadUserCreator creator : roadUserCreators) {
roadUsers.addAll(createRoadUsers(creator));
}
return roadUsers;
}
public RoadUserContainer createRoadUsers(
RoadUserCreator roadUserCreator) {
return roadUserCreator.create();
}
}
我开始为createRoadUsers编写一个测试(JUnit4 / JMock2.5.1),它返回一个带有提供创建者的RoadUserContainer。然后我开始为非参数化的createRoadUsers编写测试,以查看它是否返回一个容器,其中包含创建者返回的各个容器的所有元素:
@RunWith(JMock.class)
public class TestRoadUserCreationDaemon {
Mockery context = new JUnit4Mockery();
private RoadUserCreationDaemon daemon;
private RoadUserCreator roadUserCreator;
private SimulationManager simulationManager;
private RoadUserContainer createdRoadUsers;
@Before
public void setUp() {
simulationManager = context.mock(SimulationManager.class);
daemon = new RoadUserCreationDaemon(simulationManager);
roadUserCreator = context.mock(RoadUserCreator.class);
createdRoadUsers = context.mock(RoadUserContainer.class);
}
@Test
public void createsRoadUsersAccordingToAllAddedCreators() throws Exception {
final RoadUserCreator anotherRoadUserCreator = context.mock(RoadUserCreator.class, "anotherRUC");
final RoadUserContainer moreCreatedRoadUsers = context.mock(RoadUserContainer.class, "moreCRU");
context.checking(new Expectations() {{
oneOf (roadUserCreator).create(); will(returnValue(createdRoadUsers));
oneOf (anotherRoadUserCreator).create(); will(returnValue(moreCreatedRoadUsers));
oneOf (createdRoadUsers).roadUsersAsList();
oneOf (moreCreatedRoadUsers).roadUsersAsList();
}});
daemon.addRoadUserCreator(roadUserCreator);
daemon.addRoadUserCreator(anotherRoadUserCreator);
daemon.createRoadUsers();
//how to easily check that the two lists are equivilant - have same items, but not the same object?
//assertEquals(createdRoadUsers, daemon.createRoadUsers() );
}
@Test
public void createsRoadUsersAccordingToCreator() throws Exception {
context.checking(new Expectations() {{
oneOf (roadUserCreator).create(); will(returnValue(createdRoadUsers));
}});
assertEquals(createdRoadUsers, daemon.createRoadUsers(roadUserCreator));
}
}
正如评论所说......我不确定如何以非丑陋的方式进行。
'RoadUserContainer'界面:
public interface RoadUserContainer extends Iterable<RoadUser> {
public void add(RoadUser roadUser);
public Iterator<RoadUser> iterator();
public void addAll(RoadUserContainer createRoadUsers);
public List<RoadUser> roadUsersAsList();
public boolean equals(RoadUserContainer otherContainer);
...
}
我是TDD和嘲笑的新手,这是我的第一个> 6年的Java项目,所以请随意评论辅助美学!
答案 0 :(得分:2)
我最初可能会使用真正的容器并模拟其他对象。然后使用hamcrest来查询生成的对象。
我想要创建的测试看起来像这样:
final RoadUser roadUser0 = context.mock(RoadUser.class, "roadUser0");
final RoadUser roadUser1 = context.mock(RoadUser.class, "roadUser1");
final RoadUser roadUser2 = context.mock(RoadUser.class, "roadUser2");
final RoadUserCreator roadUserCreator0 = context.mock(RoadUserCreator.class, "roadUserCreator0");
final RoadUserCreator roadUserCreator1 = context.mock(RoadUserCreator.class, "roadUserCreator1");
final RoadUserCreationDaemon daemon = new RoadUserCreationDaemon(null);
daemon.addRoadUserCreator(roadUserCreator0);
daemon.addRoadUserCreator(roadUserCreator1);
context.checking(new Expectations() {{
oneOf(roadUserCreator0).create(); will(returnValue(roadUsers(roadUser0, roadUser1)));
oneOf(roadUserCreator1).create(); will(returnValue(roadUsers(roadUser2)));
}});
assertThat(daemon.createRoadUsers(), contains(roadUser0, roadUser1, roadUser2));
你需要从hamcrest进口这些:
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
如果订单不重要,您可以使用containsInAnyOrder而不是contains
您还需要创建实用程序方法“roadUsers”
public static RoadUserContainer roadUsers(final RoadUser... roadUsers)
{
return new RoadUserContainerImpl(roadUsers);
}
另一种设计是改变RoadUserCreationDaemon
的界面public void createRoadUsers(final RoadUserContainer roadUsers) {
for (final RoadUserCreator roadUserCreator : roadUserCreators) {
roadUsers.addAll(roadUserCreator.create());
}
}
然后你可以写下这样的测试:
final RoadUserContainer roadUserContainer0 = context.mock(RoadUserContainer.class, "roadUserContainer0");
final RoadUserContainer roadUserContainer1 = context.mock(RoadUserContainer.class, "roadUserContainer1");
final RoadUserContainer resultRoadUserContainer = context.mock(RoadUserContainer.class, "resultRoadUserContainer");
final RoadUserCreator roadUserCreator0 = context.mock(RoadUserCreator.class, "roadUserCreator0");
final RoadUserCreator roadUserCreator1 = context.mock(RoadUserCreator.class, "roadUserCreator1");
final RoadUserCreationDaemon daemon = new RoadUserCreationDaemon(null);
daemon.addRoadUserCreator(roadUserCreator0);
daemon.addRoadUserCreator(roadUserCreator1);
context.checking(new Expectations() {
{
oneOf(roadUserCreator0).create();
will(returnValue(roadUserContainer0));
oneOf(roadUserCreator1).create();
will(returnValue(roadUserContainer1));
oneOf(resultRoadUserContainer).addAll(roadUserContainer0);
oneOf(resultRoadUserContainer).addAll(roadUserContainer1);
}
});
daemon.createRoadUsers(resultRoadUserContainer);
如果对“addAll”的调用顺序很重要,您可以使用jmock sequence
答案 1 :(得分:1)
我想我会嘲笑造物主,但让它归还真正的容器。测试的想法是确保守护进程调用了所有创建者的创建方法,对吧?所以你的测试条件看起来像是
RoadUserContainer result = daemon.createRoadUsers();
// Check that the result contains both creator's users
Assert.assertEquals(createdRoadUsers.size() + moreCreatedRoadUsers.size(), result.size());
for (RoadUser user : createdRoadUsers)
Assert.assertTrue(result.contains(user));
for (RoadUser user : moreCreatedRoadUsers)
Assert.assertTrue(result.contains(user));