使用Robolectric和Mockito对android服务层进行单元测试(改装)
我开发了一个android应用程序,它集成了改进版2.0,但我添加了一些服务调用,并希望为其编写单元测试 我决定使用Robolectric,因为它可以单独运行,我可以使用CI集成运行,并且可以模拟我决定使用Mockito的对象 现在我有了一个Api类和它的实现使用Robolectric和Mockito对android服务层进行单元测试(改装),android,unit-testing,mockito,robolectric,Android,Unit Testing,Mockito,Robolectric,我开发了一个android应用程序,它集成了改进版2.0,但我添加了一些服务调用,并希望为其编写单元测试 我决定使用Robolectric,因为它可以单独运行,我可以使用CI集成运行,并且可以模拟我决定使用Mockito的对象 现在我有了一个Api类和它的实现 public interface NellyApi { // Get Api Access Token @FormUrlEncoded @POST("/oauth/token") Call<Auth
public interface NellyApi {
// Get Api Access Token
@FormUrlEncoded
@POST("/oauth/token")
Call<Authorization> requestApiToken(@Header("Authorization") String token,@FieldMap Map<String,String> fields);
//Get Product by brand
@Headers({
"xx: x",
"xx: x",
"content-type: application/json",
})
}
public class NellyWebService {
private final String TAG = "NellyWebService";
private NellyApi api;
private static NellyWebService service;
private final String SERVICE_ENDPOINT = "URL";
private Retrofit retrofit;
private String authorizationToken;
private NellyWebService(){
retrofit = new Retrofit.Builder()
.baseUrl(SERVICE_ENDPOINT)
.addConverterFactory(GsonConverterFactory.create())
.build();
api = retrofit.create(NellyApi.class);
}
public static NellyWebService getInstance(){
if(service == null){
service = new NellyWebService();
}
return service;
}
public void getApiAccessToken(){
String clientId ="x";
String clientSecret="xxx";
String credentials = clientId+ ":" + clientSecret;
String base64EncodedCredentials = Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
String authHeader = "xx " + base64EncodedCredentials;
Map<String, String> params = new HashMap();
params.put("scope","xx");
params.put("grant_type","xxx");
authorization = api.requestApiToken(authHeader,params);
authorization.enqueue(new Callback<Authorization>() {
@Override
public void onResponse(Call<Authorization> call, Response<Authorization> response) {
if(response.body() != null){
Log.d(TAG,response.body().toString());
authorizationToken = response.body().getAccessToken();
//callBack.onResponseSuccess(response.code());
statusCode = 200;
}
}
@Override
public void onFailure(Call<Authorization> call, Throwable t) {
Log.d(TAG,t.toString());
//callBack.onFail();
statusCode = 200;
}
});
}
}
公共接口NellyApi{
//获取Api访问令牌
@FormUrlEncoded
@POST(“/oauth/token”)
调用requestApiToken(@Header(“Authorization”)字符串令牌,@FieldMap字段);
//通过品牌获得产品
@标题({
“xx:x”,
“xx:x”,
“内容类型:应用程序/json”,
})
}
这就是它的实现
public interface NellyApi {
// Get Api Access Token
@FormUrlEncoded
@POST("/oauth/token")
Call<Authorization> requestApiToken(@Header("Authorization") String token,@FieldMap Map<String,String> fields);
//Get Product by brand
@Headers({
"xx: x",
"xx: x",
"content-type: application/json",
})
}
public class NellyWebService {
private final String TAG = "NellyWebService";
private NellyApi api;
private static NellyWebService service;
private final String SERVICE_ENDPOINT = "URL";
private Retrofit retrofit;
private String authorizationToken;
private NellyWebService(){
retrofit = new Retrofit.Builder()
.baseUrl(SERVICE_ENDPOINT)
.addConverterFactory(GsonConverterFactory.create())
.build();
api = retrofit.create(NellyApi.class);
}
public static NellyWebService getInstance(){
if(service == null){
service = new NellyWebService();
}
return service;
}
public void getApiAccessToken(){
String clientId ="x";
String clientSecret="xxx";
String credentials = clientId+ ":" + clientSecret;
String base64EncodedCredentials = Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
String authHeader = "xx " + base64EncodedCredentials;
Map<String, String> params = new HashMap();
params.put("scope","xx");
params.put("grant_type","xxx");
authorization = api.requestApiToken(authHeader,params);
authorization.enqueue(new Callback<Authorization>() {
@Override
public void onResponse(Call<Authorization> call, Response<Authorization> response) {
if(response.body() != null){
Log.d(TAG,response.body().toString());
authorizationToken = response.body().getAccessToken();
//callBack.onResponseSuccess(response.code());
statusCode = 200;
}
}
@Override
public void onFailure(Call<Authorization> call, Throwable t) {
Log.d(TAG,t.toString());
//callBack.onFail();
statusCode = 200;
}
});
}
}
公共类NellyWebService{
私有最终字符串标记=“NellyWebService”;
私有NellyApi api;
专用静态NellyWebService服务;
私有最终字符串SERVICE_ENDPOINT=“URL”;
私人改装;
私有字符串授权令牌;
私用NellyWebService(){
改装=新改装.Builder()
.baseUrl(服务端点)
.addConverterFactory(GsonConverterFactory.create())
.build();
api=改装.create(NellyApi.class);
}
公共静态NellyWebService getInstance(){
if(服务==null){
服务=新的NellyWebService();
}
回程服务;
}
public void getApiAccessToken(){
字符串clientId=“x”;
字符串clientSecret=“xxx”;
字符串凭据=clientId+:“+clientSecret;
字符串base64EncodedCredentials=Base64.encodeToString(credentials.getBytes(),Base64.NO_WRAP);
字符串authHeader=“xx”+base64EncodedCredentials;
Map params=新的HashMap();
参数put(“范围”、“xx”);
参数put(“授予类型”、“xxx”);
authorization=api.requestApiToken(authHeader,params);
authorization.enqueue(新回调(){
@凌驾
公共void onResponse(调用、响应){
if(response.body()!=null){
Log.d(标记,response.body().toString());
authorizationToken=response.body().getAccessToken();
//callBack.onResponseSuccess(response.code());
状态代码=200;
}
}
@凌驾
失败时公共无效(调用调用,可丢弃的t){
Log.d(TAG,t.toString());
//callBack.onFail();
状态代码=200;
}
});
}
}
基本上,我想编写测试用例来测试这个api是否工作,并检查它是否给出了正确的响应(输出数据与给定数据匹配)
我该怎么做?我应该如何编写单元测试来检查这一点
我已经为此编写了一个单元测试,但还不清楚如何从这开始
@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP)
public class NellyWebServiceTest {
private NellyWebService apiImpl;
@Captor
private ArgumentCaptor<Callback<CountryListResponse>> cb;
@Captor
private ArgumentCaptor<ResponseCallBack> cb1;
@Mock
private Call<CountryListResponse> countryListCall;
@Before
public void setUp(){
MockitoAnnotations.initMocks(this);
apiImpl = NellyWebService.getInstance();
}
@Test
public void testApiAuthorization() throws Exception{
}
@Test
public void testGetCountryList() throws Exception{
apiImpl.getApiAccessToken();
await().until(newUserIsAdded());
CountryListResponse res = apiImpl.getResponseInstance();
}
private Callable<Boolean> newUserIsAdded() {
return new Callable<Boolean>() {
public Boolean call() throws Exception {
return apiImpl.getStatusCode() != 0; // The condition that must be fulfilled
}
};
}
}
@RunWith(RobolectrictTestRunner.class)
@配置(常量=BuildConfig.class,sdk=Build.VERSION\u code.LOLLIPOP)
公共类NellyWebServiceTest{
私人NellyWebService APIMPL;
@俘虏
私人辩手;
@俘虏
私人辩手cb1;
@嘲弄
私人通话;
@以前
公共作废设置(){
initMocks(this);
apimpl=NellyWebService.getInstance();
}
@试验
public void testipAuthorization()引发异常{
}
@试验
public void testGetCountryList()引发异常{
apimpl.getApiAccessToken();
等待()。直到(newUserIsAdded());
CountryListResponse res=apimpl.getResponseInstance();
}
私有可调用newUserIsAdded(){
返回新的可调用(){
公共布尔调用()引发异常{
返回apimpl.getStatusCode()!=0;//必须满足的条件
}
};
}
}
如果getApiAccessToken
方法接受回调,那么就容易多了,这样您就可以知道回调何时完成。但是你期待什么样的答案呢?你在找人为你写测试吗?你看过关于机器人分子和/或Mockito的教程吗?你写过测试代码吗?@nasch是的,我写过,我的问题在一些事情上不清楚,比如我必须测试哪种方法?getApiAccessToken()或requestApiToken()@nasch已经创建了一个类,您能指出我缺少了什么吗?不,您不需要直接测试requestApiToken
,因为getApiToken
已经调用了它。但是,我再次向getApiToken
推荐一个回调参数,这样您就可以轻松地返回结果。还可以查看异步操作的等待性。如果您不采取措施,您的测试将在异步操作之前完成。“集成awailitiy和yes需要添加它sync这是一个异步调用,但当我运行case时,它会滞后,@nasch”