使用Robolectric和Mockito对android服务层进行单元测试(改装)

使用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

我开发了一个android应用程序,它集成了改进版2.0,但我添加了一些服务调用,并希望为其编写单元测试

我决定使用Robolectric,因为它可以单独运行,我可以使用CI集成运行,并且可以模拟我决定使用Mockito的对象

现在我有了一个Api类和它的实现

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”