2011-10-17 6 views
2

メソッドが、模擬オブジェクトによって返された複数の他のコンテナの集合であるコレクションをカプセル化するコンテナを返すかどうかをチェックする方法を知りたいと思います。つまり、個々のコンテナのすべての要素が含まれています。私はいくつかのテストをコンテナの 'works'(add/addAll/etcなど)をチェックしているので、そのことは分かっていますが、 'createsRoadUsersAccordingToAllAddedCreators'の下のテストではどうなっているのか分かりません。コレクションをカプセル化したオブジェクトを模倣する

私は、作成したRoadUserCreationDaemonクラスを追加しました。このクラスは、追加された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(); 
    } 
} 

私は供給クリエイターとRoadUserContainerを返しcreateRoadUsersためのテストを(JUnit4/JMock2.5.1)書き込むことによって開始しました。私はないんだけど...コメントが言うように

@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)); 
    } 
} 

:その後、私はそれはクリエイターによって返された個々のコンテナのすべての要素の入った容器を返すかどうかを確認するために、非パラメータ化createRoadUsersのためのテストを書き始めどのように非醜い方法で進むことを確認してください。

「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プロジェクトであるので、補助的な美学にコメントして自由に感じます!

答えて

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

私はクリエイターを模倣するが、実際のコンテナは返すと思う。テストのアイデアは、デーモンがすべての作成者の作成メソッドを呼び出すことを確認することです。あなたのテスト条件は次のようになります

+0

あなたの基準実際のコンテナを作成するのは問題ありません。なぜなら、コンテナは「値」オブジェクトのままであるからです。 – neuronotic

+0

これは値オブジェクトである必要はありません。デーモンによって作成されたコンテナに、2つの作成者オブジェクトによって作成されたすべてのユーザーが含まれていることを確認するだけです。それは理にかなっていますか? – jeff

+0

ええ、私は理解していると思う - それは現在どのように進行しているのですか(ありがと;))。しかし、それはまだ他のオブジェクトの実際の実装にそれをカップリングさせる臭いのビットを残しているようです。私は答えをアップに投票しましたが、私はそれを1日または3日に答えてマーキングするのを延期します。 – neuronotic

関連する問題