我在我的应用程序中使用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();
}
但是这段代码不起作用。
答案 0 :(得分:3)
我参加聚会的时间有点晚了,但这里有一个可以解决异步调用的类的例子。我们只是让它做它并将其注册到下面的TestDriver
类中,而不是模拟EventBus。
使这项工作成功的是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();
}
}
答案 1 :(得分:1)
它不起作用,因为instance
不是模拟。您必须验证callAMethod
的效果或将该方法放在另一个类中,并将此新类的模拟注入您的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();
}
希望这有帮助。