单元测试的好方法Retrofit接口声明

问题描述 投票:3回答:1

我有下一个接口声明:

public interface FundaService
{
    @GET( "/feeds/Aanbod.svc/json/{key}" )
    Observable<JsonResponse> queryData( @Path( "key" ) String key, @Query("type" ) String type, @Query( "zo" ) String search, @Query( "page" ) int page, @Query( "pagesize" ) int pageSize );
}

我用Retrofit后用。什么是一种优雅的测试方式,我没有在URL声明和查询参数中犯错?

我看到我可以模拟web层并检查带参数的url。

UPDATE

我修改了它:

public interface FundaService
{

    String KEY_PATH_PARAM = "key";
    String FEED_PATH = "/feeds/Aanbod.svc/json/{" + KEY_PATH_PARAM + "}";
    String TYPE_QUERY_PARAM = "type";
    String SEARCH_QUERY_PARAM = "zo";
    String PAGE_QUERY_PARAM = "page";
    String PAGESIZE_QUERY_PARAM = "pagesize";

    @GET( FEED_PATH )
    Observable<JsonResponse> queryData( @Path( KEY_PATH_PARAM ) String key, @Query( TYPE_QUERY_PARAM ) String type,
                                        @Query( SEARCH_QUERY_PARAM ) String search, @Query( PAGE_QUERY_PARAM ) int page,
                                        @Query( PAGESIZE_QUERY_PARAM ) int pageSize );
}

并部分测试它,如:

public class FundaServiceTest
{
    @Test
    public void PathKeyIsCorrect()
        throws Exception
    {
        assertThat( FundaService.KEY_PATH_PARAM ).isEqualTo( "key" );
    }

    @Test
    public void FeedPathIsCorrect()
        throws Exception
    {
        assertThat( FundaService.FEED_PATH ).isEqualTo( "/feeds/Aanbod.svc/json/{key}" );
    }
}
android unit-testing retrofit
1个回答
3
投票

您可以使用okhttp拦截器来检查由改造构建的最终请求,而无需使用模拟http服务器。它让您有机会更早地检查请求。假设我们要测试以下界面 -

public interface AwesomeApi {
  @GET("/cool/stuff")
  Call<Void> getCoolStuff(@Query(("id"))String id);
}

第一个测试运行'validateEagerly`来验证整个接口。如果您的其他测试用例没有触及所有接口方法,则非常有用。第二个测试是一个示例,说明如何验证特定调用是否正在生成预期的URL。

public class AwesomeApiTest {

  @Test
  public void testValidInterface() {
    Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://www.example.com/")
        .addConverterFactory(GsonConverterFactory.create())
        // Will throw an exception if interface is not valid
        .validateEagerly()
        .build();
    retrofit.create(AwesomeApi.class);
  }

  @Test(expected = NotImplementedException.class)
  public void testCoolStuffRequest() throws Exception {
    OkHttpClient client = new OkHttpClient();
    client.interceptors().add(new Interceptor() {
      @Override
      public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
        final Request request = chain.request();
        // Grab the request from the chain, and test away
        assertEquals("HTTP methods should match", "GET", request.method());
        HttpUrl url = request.httpUrl();
        // Test First query parameter
        assertEquals("first query paramter", "id", url.queryParameterName(0));
        // Or, the whole url at once --
        assertEquals("url ", "http://www.example.com/cool/stuff?id=123", url.toString());
        // The following just ends the test with an expected exception.
        // You could construct a valid Response and return that instead
        // Do not return chain.proceed(), because then your unit test may become
        // subject to the whims of the network
        throw new NotImplementedException();
      }
    });
    Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://www.example.com/")
        .addConverterFactory(GsonConverterFactory.create())
        .client(client)
        .build();
    AwesomeApi awesomeApi = retrofit.create(AwesomeApi.class);
    awesomeApi.getCoolStuff("123").execute();;
  }
}

我从浏览改造自己的测试中得到了这个想法。其他人的测试往往是很大的灵感!

© www.soinside.com 2019 - 2024. All rights reserved.