使用RequestFactory / Activities进行GWT单元测试

时间:2014-10-14 14:49:01

标签: unit-testing gwt junit mockito requestfactory

我试图测试使用RequestFactory的Activity的start方法。

我设法测试使用this article example直接调用服务的RF呼叫,但是我错过了从测试活动调用的模拟RF呼叫的内容。

代码更清晰。

编辑:更具体

我真正想知道的是,如何替换Activity中调用的Receiver方法(onSuccess,onFailure ...)的响应?这样我就能够在接收器方法中测试代码。

所以基本上这是我的活动:

public class MyActivity extends AbstractActivity implements MyView.Presenter {
    private List<MyEntityProxy> entities;
    private MyView view;
    private ClientFactory cf;
    private EntityRequest entityRequest;
    private AppRequestFactory rf;

    @Inject
    public ClientsListActivity(ClientsListViewEditor view, ClientFactory clientFactory) {
        this.view = view;
        this.clientFactory = clientFactory;
        rf = clientFactory.getRequestFactory();
    }

    @Override
    public void start(final AcceptsOneWidget panel, EventBus eventBus) {
        view.setPresenter(this);
        refreshEntities();
    }

    public void refreshEntities(){
         entityRequest = rf.entityRequest();
         entityRequest.getAll().with("opt1,"opt2").fire(new Receiver<List<MyEntityProxy>>() {
             @Override
            public void onSuccess(List<MyEntityProxy> response) {
                entities = response;
                entityRequest = requestFactory.clientRequest();
             }
         });
    }
    public List<MyEntityProxy> getEntities(){
        return entities;
    }
}

要在JUnit中测试它我使用GwtMockito,所以这里是测试类MyActivityTest:

@RunWith(GwtMockitoTestRunner.class)
public class ClientListActivityTest{

    private MyActivity activity;
    private EventBus eventBus;
    private AppRequestFactory rf;
    @GwtMock
    private ClientFactory cf;
    @GwtMock
    private MyView;
    @GwtMock
    private AcceptsOneWidget panel;

    @Before
    public void setUp(){
        eventBus = new SimpleEventBus();
        rf = RequestFactoryHelper.create(AppRequestFactory.class);
        cf = new ClientFactory(eventBus,rf);
        activity = new MyActivity(view,cf);

    }

    @Test
    public void testStartActivity(){
        List<EntityProxy> result = new ArrayList<EntityProxy>();
        EntityProxy expectedClient = mock(EntityProxy.class);
        expectedEntity.setNom("Client 1");
        EntityProxy expectedClient2 = mock(EntityProxy.class);
        expectedEntity.setNom("Client 2");
        result.add(expectedEntity);
        result.add(expectedEntity2);
        //Here I have to change the requestFactory Call, so I try that but without success :
        Request<?> req = mock(Request.class);
        doReturn(req).when(mock(MyEntityRequest.class)).getAll();

        doAnswer(RequestFactoryHelper.ok(result)).when(req).fire(any(Receiver.class));
        activity.start(panel, eventBus);
        assertEquals(activity.getEntities().size(),2); //This Test fails size = 0
    }


}

我的RequestFactoryHelper(灵感来自here):

public class RequestFactoryHelper {

    private static class MockServiceLocator implements ServiceLocator {
        private final Map<Class<?>, Object> services = new HashMap<Class<?>, Object>();

        @Override
        public Object getInstance( Class<?> clazz ) {
            // Make sure to return always the same mocked instance for each requested type
            Object result = services.get( clazz );
            if (result == null) {
                result = mock( clazz );
                services.put( clazz, result );
            }
            return result;
        }
    }

    private static class MockServiceDecorator extends ServiceLayerDecorator {
        @Override
        public <T extends ServiceLocator> T createServiceLocator( Class<T> clazz ) {
            return (T) serviceLocator;
        }
    }

    private static MockServiceLocator serviceLocator = new MockServiceLocator();
    private static ServiceLayer serviceLayer = ServiceLayer.create( new MockServiceDecorator() );

    /**
     * Creates a {@link RequestFactory}.
     */
    public static <T extends RequestFactory> T create( Class<T> requestFactoryClass ) {
        SimpleRequestProcessor processor = new SimpleRequestProcessor( serviceLayer );
        T factory = RequestFactorySource.create( requestFactoryClass );
        factory.initialize( new SimpleEventBus(), new InProcessRequestTransport( processor ) );
        return factory;
    }

    /**
     * Returns the same service instance as used by the RequestFactory internals.
     */
    public static <T> T getService( Class<T> serviceClass ) {
        T result = (T) serviceLocator.getInstance( serviceClass );
        reset( result ); // reset mock to avoid side effects when used in multiple tests
        return result;
    }

   /**
    * Returns the value passed to {@link Receiver#onSuccess(Object)}
    */
    public static <T> T captureResult( Receiver<T> receiver ) {
        ArgumentCaptor<Object> captor = ArgumentCaptor.forClass( Object.class );
        verify( receiver ).onSuccess( (T) captor.capture() );
        return (T) captor.getValue();
    }

    public static <T> Answer<T> ok(final T result) {
         return new Answer<T>() {

            @Override
            public T answer(InvocationOnMock invocation) throws Throwable {
               Object[] args = invocation.getArguments();
               Object _receiver = args[args.length - 1];
               Receiver<T> receiver = (Receiver<T>)_receiver;
               receiver.onSuccess(result);
               return null;
            }

        };
    }
}

1 个答案:

答案 0 :(得分:1)

这是我测试Receiver方法“onSuccess”的方法。我为Mockito.doAnswer创建了一个自定义答案。

要测试的代码。

public void myMethod(String arg1, String arg2) {
    requestFactory.adminRequest().someMethod(arg1, arg2).fire(new Receiver<Void>() {
        @Override
        public void onSuccess(Void response) {
            placeController.goTo(new MyPlace());
        }
    });
}

测试。

@Test
public void testMyMethod() {
    String arg1 = "arg1";
    String arg2 = "arg2";
    when(requestFactory.adminRequest()).thenReturn(adminRequest);
    when(adminRequest.someMethod(arg1, arg2)).thenReturn(request);
    doAnswer(new Answer<Void>() {

        @Override
        public Void answer(InvocationOnMock invocation) throws Throwable {
            Object[] args = invocation.getArguments();
            Receiver<Void> receiver = (Receiver<Void>) args[0];
            receiver.onSuccess(null);
            return null;
        }
    }).when(request).fire(any(Receiver.class));

    myActivity.myMethod(arg1, arg2);
    verify(adminRequest).someMethod(arg1, arg2);
    verify(request).fire(any(Receiver.class));
    verify(placeController).goTo(any(myPlace.class));

}

requestFactory,adminRequest,request和placeController都是模拟。