我在应用程序中使用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();
}
希望这能有所帮助。