我有以下内容:
- ExampleLogic.java(使用异步服务进行服务器调用的类)
- ExampleServiceAsync.java(接口 á la GWT)
- ExampleService.java(创建异步实例的接口 á la GWT)
- ExampleLogicTest(这是出现错误的地方)
我有两个简单的测试,单独运行时它们都通过了。但是当它们一个接一个地运行时(在 Eclipse 中),第二个总是失败并出现以下错误:
需要但未调用:exService.exampleServiceMethod()。实际上,与此模拟的交互为零。
我已经对服务进行了这样的注释:@GwtMock exService;
需要注意的是,调用异步服务的 ExampleLogic 类在其自己的类中创建服务。正如您在示例中看到的那样,我可以通过从测试类设置异步服务来使其工作。但后来我只需要@Mock
来自 Mockito 的代替。
它有效,因此这个问题更多是出于好奇和一点点实用性(因为感觉没有必要仅为了测试而为异步服务设置设置器)。
所以问题是:
为什么会这样?
其他问题:
有什么可做的吗?你推荐另一种测试方式吗?
希望有任何 GWT 专家可以帮助我!
使用:
JUnit 4.13
GwtMockito 1.1.9(以及随后的 Mockito:0.9.2)
ExampleLogic.java(使用异步服务进行服务器调用的类)
import com.google.gwt.user.client.rpc.AsyncCallback;
public class ExampleLogic {
public boolean callFailed; // public to simplify example
public boolean returnVal; // public to simplify example
private ExampleServiceAsync exampleService;
public void setExampleService(ExampleServiceAsync exampleService) {
this.exampleService = exampleService;
}
public void exampleCallToService() {
if (exampleService == null) {
exampleService = ExampleService.Util.getInstance(); // Problem arises here.
// I suppose GwtMockito is reusing the old one even though GwtMockito.tearDown() is called.
// That's why the second fails with the comment "There were zero interactions with this mock".
// It is actually using the first still. Why is that so and how can I make it use the second?
}
exampleService.exampleServiceMethod(new AsyncCallback<Boolean>() {
@Override
public void onSuccess(Boolean result) {
callFailed = false;
returnVal = result;
}
@Override
public void onFailure(Throwable caught) {
callFailed = true;
}
});
}
}
ExampleServiceAsync.java(接口 á la GWT)
import com.google.gwt.http.client.Request;
import com.google.gwt.user.client.rpc.AsyncCallback;
public interface ExampleServiceAsync {
public Request exampleServiceMethod(AsyncCallback<Boolean> callback);
}
ExampleService.java(创建异步实例的接口 á la GWT)
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.RemoteService;
public interface ExampleService extends RemoteService {
public static class Util {
private static ExampleServiceAsync instance = null;
public static ExampleServiceAsync getInstance(){
if (instance == null) {
instance = (ExampleServiceAsync) GWT.create(ExampleService.class);
}
return instance;
}
}
boolean exampleServiceMethod();
}
ExampleLogicTest(这是出现错误的地方)
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.Mockito;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwtmockito.GwtMock;
import com.google.gwtmockito.GwtMockito;
import com.google.gwtmockito.GwtMockitoTestRunner;
@RunWith(GwtMockitoTestRunner.class)
public class ExampleLogicTest {
@GwtMock ExampleServiceAsync exService;
// @Mock ExampleServiceAsync exService; // Can be used if the service is set manually
@Captor ArgumentCaptor<AsyncCallback<Boolean>> callbackCaptor;
ExampleLogic exLogic;
@Before
public void init() {
GwtMockito.initMocks(this); // Doesn't make any difference to comment/uncomment.
exLogic = new ExampleLogic();
// exLogic.setExampleService(exService); // Uncommenting this will make both tests pass in a single run. Otherwise the second to run will always fail. Or running separately they'll pass.
}
@After
public void tearDown() {
GwtMockito.tearDown(); // Doesn't make any difference to comment/uncomment.
}
@Test
public void test1_SuccessfulCall() {
exLogic.exampleCallToService();
Mockito.verify(exService).exampleServiceMethod(callbackCaptor.capture());
AsyncCallback<Boolean> callback = callbackCaptor.getValue();
callback.onSuccess(true);
assertFalse(exLogic.callFailed);
assertTrue(exLogic.returnVal);
}
@Test
public void test2_FailedCall() {
exLogic.exampleCallToService();
Mockito.verify(exService).exampleServiceMethod(callbackCaptor.capture());
AsyncCallback<Boolean> callback = callbackCaptor.getValue();
callback.onFailure(new Throwable());
assertTrue(exLogic.callFailed);
assertFalse(exLogic.returnVal);
}
}