如何在android中对事件总线发布的方法进行单元测试



我在应用程序中使用Otto的事件总线。在我的一个班级里,我发布了这个活动。

MyEvent myevent = new MyEvent();
uiBus.post(myEvent);

我能够测试post方法。

现在有另一个类正在接收事件。

//ReceiverClass.java
@Subscribe
public void onEventReceived(MyEvent myevent) {
    callAMethod();
}

我该如何对调用该方法进行单元测试。我尝试了以下测试代码

@Mock
Bus uiBus;
@Test
public void testBusReceviedEvent() {
    ReceiverClass instance = new ReceiverClass();
    mockBus.register(instance);
    MyEvent myevent = new MyEvent();
    mockBus.post(myEvent);
    //Test
    verify(instance, times(1)).callAMethod();
}

但是这个代码不起作用。

我来晚了一点,但这里有一个类的例子,它可以工作并解释异步调用。与Mocking EventBus不同,我们只是让它做它自己的事情,并在下面的TestDriver类中注册它。

使这项工作起作用的是CountDownLatch,它在抽象DataTransferCallback类的帮助下,等待调用latch.countDown()或经过5秒

只需注册您的测试类,然后在@Subscribe方法中,将其传递回创建DataTransferCallback的方法,并在那里进行断言。

@RunWith(AndroidJUnit4.class)
public class TestDriver {
    private final CountDownLatch latch = new CountDownLatch(1);
    private EventBus eventBus;
    private DataTransferCallback transferCallback;
    public abstract class DataTransferCallback {
        abstract void onSuccess(DataTransfer event);
    }
    @Before
    public void setUp() {
        EventBus.getDefault().register(this);
        eventBus = spy(EventBus.getDefault());
    }

    @SuppressWarnings("unchecked")
    @Test
    public void test200Resposne() throws InterruptedException {
    // Get known good JSON
    final String json = TestJSON.get200Response();
    // Class under test
    final Driver driver = new Driver(InstrumentationRegistry.getTargetContext());
    final JsonParser jsonParser = new JsonParser();
    //boolean to hold our test result
    final boolean[] testPassed = new boolean[]{false};
    transferCallback = new DataTransferCallback() {
        @Override
        public void onSuccess(DataTransfer event) {
            assertNotNull(event);
            verify(eventBus).post(event);
            assertThat(event.getStatus(), is("OK"));
            assertTrue(event.getData() != null);
            testPassed[0] = true;
        }
    };
    //Set our test EventBus object
    driver.setEventBus(eventBus);
    // The actual method under test
    driver.parseData(jsonParser.parse(json));
    // Set a countdown latch to wait for the result (5s)
    latch.await(5000, TimeUnit.MILLISECONDS);
    // will wait here until 5s or the @Subscrube method is hit
    assertTrue(testPassed[0]);
}
//Because we want to examine EventBus Output, register it 
//to this class and pass the event back through our custom abstract class
@Subscribe
public void onReceiveEventBusEvent(DataTransfer event) {
    assertNotNull(transferCallback);
    transferCallback.onSuccess(event);
    //notify latch so that we can proceed
    latch.countDown();
    }
}

它不起作用,因为instance不是mock。您必须验证callAMethod的效果,或者将该方法放在另一个类中,并将这个新类的mock注入到ReceiverClass类中。

例如。。。

private class ReceiverClass {
    private MyNewClass theNewClassIWasTalkingAbout;
    // Stick in a setter for that ^
    @Subscribe
    public void onEventReceived(MyEvent myevent) {
        theNewClassIWasTalkingAbout.callAMethod();
    }
}

然后你的测试将不得不稍微改变。。。

@Mock
private MyNewClass mockNewClass;
@InjectMocks // This will be the "solid" implementation of the thing you are trying to test, it is not a mock...
private ReceiverClass instance;
@Test
public void testBusReceivedEvent() {
    mockBus.register(instance);
    MyEvent myevent = new MyEvent();
    mockBus.post(myevent);
    verify(mockNewClass, times(1)).callAMethod();
}

希望这能有所帮助。

相关内容

  • 没有找到相关文章

最新更新