0

GIN を組み合わせたアクティビティと場所を使用した GWT MVP パターンは初めてです。Mockito を使用して GWT プロジェクトの JUnit テスト ケースを書き始めました。多くのブログが、パフォーマンスのために GWT テスト ケースを使用しないことを示唆していたため、Mockito を使用することにしました。プレゼンターの 1 人のテスト ケースを書いています。GIN を使用して Presenter のほとんどのインスタンスを作成しているため、Gin Injector オブジェクトをモックする必要があります。Junit テスト ケースでは、Gin インジェクタをモックできません。Junit テスト ケースでは Gin を使用できないことをどこかで読みましたが、代わりに Guice を使用する必要があります。私の質問は、Mockito を使用して Gin インジェクターをモックするにはどうすればよいですか? 私のプロジェクトで行ったのとまったく同じパターンを使用したテスト ケースをいくつか見つけましたが、代わりに Client Factory を使用していました。テスト ケースでクライアント ファクトリを GIN に置き換えることに失敗しました。オンラインで見つけたコードは次のとおりで、テスト ケースで Client Factory を GIN インジェクターに置き換える必要があります。

@RunWith(MockitoJUnitRunner.class) public class ContactListActivityTest {

@Mock
private IClientFactory clientFactoryMock;

@Mock
private PlaceController placeControllerMock;

@Mock
private IContactListView contactListViewMock;

@Mock
private AcceptsOneWidget acceptsOneWidgetMock;

@Mock
private IContactServiceAsync contactServiceAsyncMock;

@Mock
private EventBus eventBusMock;

private List<Contact> contacts;
private Contact contact1;
private Contact contact2;

@SuppressWarnings("unchecked")
@Before
public void setUp() throws Exception {
    when(clientFactoryMock.getPlaceController()).thenReturn(placeControllerMock);
    when(clientFactoryMock.getContactListView()).thenReturn(contactListViewMock);
    when(clientFactoryMock.getContactService()).thenReturn(contactServiceAsyncMock);

    Answer<Void> answer = new Answer<Void>() {
        @Override
        public Void answer(InvocationOnMock invocation) {
            Object[] args = invocation.getArguments();
            AsyncCallback<List<Contact>> asyncCallback = (AsyncCallback<List<Contact>>) args[0];
            contact1 = new Contact();
            contact1.setFirstName("Kai");
            contact1.setLastName("Toedter");
            contact1.setEmail("kai@toedter.com");
            contact2 = new Contact();
            contact2.setFirstName("Kai2");
            contact2.setLastName("Toedter2");
            contact2.setEmail("kai2@toedter.com");
            final List<Contact> contacts2 = new ArrayList<Contact>();
            contacts2.add(contact1);
            contacts2.add(contact2);
            asyncCallback.onSuccess(contacts2);
            return null;
        }
    };

    doAnswer(answer).when(contactServiceAsyncMock).getAllContacts(any(AsyncCallback.class));

    // set the real contacts object, when clientFactory.setContacts is
    // called
    Answer<Void> setContactsAnswer = new Answer<Void>() {
        @Override
        public Void answer(InvocationOnMock invocation) throws Throwable {
            contacts = (List<Contact>) invocation.getArguments()[0];
            // System.out.println("answer() to setContacts(): " + contacts);
            return null;
        }
    };

    doAnswer(setContactsAnswer).when(clientFactoryMock).setContacts(any(List.class));

    // Return the real contacts object, when clientFactory.getContacts is
    // called
    Answer<List<Contact>> getContactsAnswer = new Answer<List<Contact>>() {
        @Override
        public List<Contact> answer(InvocationOnMock invocation) throws Throwable {
            return contacts;
        }
    };

    doAnswer(getContactsAnswer).when(clientFactoryMock).getContacts();
}

@Test
public void testGotoPlace() {
    ContactListActivity contactListActivity = new ContactListActivity(new ContactPlace(null), clientFactoryMock);

    ContactPlace contactPlace = new ContactPlace("kai@toedter.com");
    contactListActivity.goTo(contactPlace);

    verify(placeControllerMock).goTo(contactPlace);
}

@Test
public void testStartWithEmptyToken() {
    clientFactoryMock.setContacts(null); // force RCP
    ContactListActivity contactListActivity = new ContactListActivity(new ContactPlace(""), clientFactoryMock);
    contactListActivity.start(acceptsOneWidgetMock, eventBusMock);

    verify(contactListViewMock).setPresenter(contactListActivity);
    verify(contactListViewMock).initialize(contacts);
}

@Test
public void testStartWithToken() {
    String token = "kai@toedter.com";
    clientFactoryMock.setContacts(null); // force RCP

    ContactListActivity contactListActivity = new ContactListActivity(new ContactPlace(token), clientFactoryMock);
    contactListActivity.start(acceptsOneWidgetMock, eventBusMock);

    verify(contactListViewMock).setPresenter(contactListActivity);
    verify(contactListViewMock).initialize(contacts);
    verify(contactListViewMock).selectInitialContact(contact1);
    verify(eventBusMock).fireEvent(any(ContactViewEvent.class));
}

@Test
public void testMayStop() {
    ContactListActivity contactListActivity = new ContactListActivity(new ContactPlace(null), clientFactoryMock);
    contactListActivity.start(acceptsOneWidgetMock, eventBusMock);
    contactListActivity.mayStop();

    verify(contactListViewMock).setPresenter(null);
}

@Test
public void clientFactoryTest() {
    List<Contact> testList = new ArrayList<Contact>();
    clientFactoryMock.setContacts(testList);
    Assert.assertNotNull(clientFactoryMock.getContacts());
}

}

助けてください。

4

2 に答える 2

1

コードがに依存している場合は、問題があります。直接の依存関係Ginjectorを注入していません。オブジェクトのファクトリが必要な場合は、を挿入します。Provider

ただし、あなたの場合は、共有状態値ホルダー、または;のローカルキャッシュとしてIClientFactoryも機能します。これは、単一責任の原則に違反することを意味します。List<Contact>IClientFactory

したがって、最初にローカルキャッシュの責任を独自のオブジェクト(ContactListCacheオブジェクトなどValueHolder<List<Contact>>)に抽出してから、そのオブジェクトのインスタンスを挿入します。
そしてもちろん、PlaceControllerビューとGWT-RPCサービスを直接注入します。

しかし実際には、コードをリファクタリングしてキャッシュから取得を抽出するか、サーバーの責任を独自のContactListHolderオブジェクトに要求します(または、GWT-RPCを使用している場合は、IContactServiceAsyncインターフェイスをラッパーとして実装できますによって生成されGWT.create()、キャッシュ動作が追加されます。いくつかのインスピレーションについては、 http://www.google.com/events/io/2009/sessions/GoogleWebToolkitBestPractices.htmlを参照してください)。これにより、アクティビティのコードが大幅に簡素化されます。


ちなみに、このコードはモックを多用している可能性があります。実際のPlaceController(およびspy()そのgoTo(Place)メソッドを使用する)およびaSimpleEventBusまたは?を使用しないのはなぜCountingEventBusですか?

于 2012-09-06T08:19:48.360 に答える