![](/img/trans.png)
[英]Mockito Unit Tests stubbing a method throws NullPointerException
[英]Android Tests: Stubbing out Retrofit with Mockito
在我的MainActivity
我有一個名為getAPI
的方法,它返回一個OTBServiceWrapper
。 這用於設置用於調用API的改進。
在我的MainActivityTest
文件中,我試圖找出getApi
方法正在進行的new OTBService().getService()
調用,這樣我就可以返回一個MockedOTBService
,它將客戶端更改為返回json
的自定義客戶端。
MockedOTBService
如果我不得不在MockedOTBService
放置一個記錄器但是它也會通過並調用真正的api,那么當前的實現將是MockedOTBService
,這在測試中不是我想要的。
我試圖使用Mockito存根Retrofit API調用並返回json
。 我似乎無法理解為什么存根被調用尚未存在問題的方法。
筆記:
ActivityInstrumentationTestCase2
verify(mockedOTBService, atLeastOnce()).getService();
據說它從未被稱為。 when...thenReturn
使用mMainActivity = spy(getActivity())
則沒有更改並且會調用真正的API。 Logcat輸出
Logger﹕ MockedOTBService was called // Mock is called
Logger﹕ Real OTBService was called // Real API is called
Logger﹕ MainActivity getAPI method class is "$Proxy1" // Mock is shown in MainActivity
Logger﹕ RealAPIResponse JSON Parsed ID: 266 // Real API response returned
真正的流量
MainActivity.onCreate()> OTBService.getService()> OTBServiceWrapper.createSearch(...)
試圖在測試中實現
MainActivity.onCreate()> MockedOTBService.getService()> OTBServiceWrapper.createSearch(...)
MainActivity.java
public class MainActivity extends Activity {
private OTBServiceWrapper serviceWrapper;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getApi().createSearch(...)
}
public OTBServiceWrapper getApi() {
return new OTBService().getService();
}
}
OTBService.java
public class OTBService {
public OTBServiceWrapper getService() {
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(Constants.API_URL)
.build();
return restAdapter.create(OTBServiceWrapper.class);
}
}
OTBServiceWrapper.java
public interface OTBServiceWrapper {
@POST(Constants.API_SEARCHES_POST_URL)
void createSearch(@Body Request request, Callback<Request.Response> callback);
}
MainActivityTest.java
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
private OTBService mMockedOTBService;
private MainActivity mMainActivity;
private View mSearchButton;
public MainActivityTest() { super(MainActivity.class); }
@Override
protected void setUp() throws Exception {
super.setUp();
setActivityInitialTouchMode(true);
System.setProperty("dexmaker.dexcache", getInstrumentation().getTargetContext().getCacheDir().getPath());
mMockedOTBService = mock(OTBService.class);
when(mMockedOTBService.getService()).thenReturn(new MockedOTBService(getInstrumentation().getContext()).getService());
mMainActivity = getActivity();
mSearchButton = mMainActivity.findViewById(R.id.AbSearchButton);
mYourHolidayButton = mMainActivity.findViewById(R.id.AbYourHolidayButton);
}
public void testButtonActions() {
TouchUtils.clickView(this, mSearchButton);
...
}
}
MockedOTBService.java
public class MockedOTBService {
private Context context;
public MockedOTBService(Context context) { this.context = context; }
public OTBServiceWrapper getService() {
RestAdapter restAdapter;
restAdapter = new RestAdapter.Builder()
.setClient(new LocalJsonClient(context))
.setEndpoint(Constants.API_TEST_URL)
.build();
return restAdapter.create(OTBServiceWrapper.class);
}
}
LocalJsonClient.java
@SuppressLint("DefaultLocale")
public class LocalJsonClient implements Client { ... }
的build.gradle
dependencies {
androidTestCompile 'com.google.dexmaker:dexmaker:1.0'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.0'
}
通過允許Activity設置服務,無需模擬您的請求。
在MainActivity
,為服務創建一個類變量和一個類設置器。 它必須是類范圍,以防止在將服務設置為您希望的服務之前調用OnCreate
方法。 還要創建一個實例getter來設置服務(如果還沒有)。
在您調用getActivity()
之前的測試中,將服務設置為您的模擬服務。 (也許考慮將其移到支持對象)。
MainActivity.java
public class MainActivity extends Activity {
private static OTBServiceWrapper serviceWrapper;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getServiceWrapper.createSearch(...)
}
public OTBServiceWrapper getServiceWrapper() {
if (serviceWrapper == null) {
MainActivity.setServiceWrapper(new OTBService().getService());
}
return serviceWrapper;
}
public static void setServiceWrapper(OTBServiceWrapper serviceWrapper) {
MainActivity.serviceWrapper = serviceWrapper;
}
}
MainActivityTest.java
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
private MainActivity mMainActivity;
public MainActivityTest() { super(MainActivity.class); }
@Override
protected void setUp() throws Exception {
super.setUp();
setActivityInitialTouchMode(true);
MainActivity.setServiceWrapper(
new MockedOTBService(getInstrumentation().getContext()).getService()
);
mMainActivity = getActivity();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.