2013-09-04 4 views
31

Я хотел бы знать, как я могу создать модульные тесты для платформы volley. Откажитесь от запросов, ответов, чтобы я мог создавать модульные тесты, которые не требуют работы веб-службы и сетевых доступов.Тестирование устройства с помощью Android volley

Я гугл, но я не нашел много информации о рамках на всех

+2

Мое решение для насмешливого ответа создает FakeHttpStack, который реализует HttpStack. Затем вы можете получить RequestQueue как новый RequestQueue (новый NoCache(), новый BasicNetwork (новый FakeHttpStack())); – Kazuki

+0

В настоящее время есть нулевой документ, который я могу найти. Но есть много примеров, и видео Google IO 2013 также легко вникать. –

+0

@ Kazuki Можете ли вы оставить это в качестве ответа? Пока это единственный реальный ответ. –

ответ

0

Не 100% уверены, что я понимаю, что вы хотите сделать, но если я делаю, то EasyMock (а LIB что позволяет создавать макеты классов, которые вы можете совершать вызовы и получать предопределенные ответы) поможет вам многое. У парня под названием Lars Vogel есть хорошая статья по этой теме, которую я нашел полезной, когда я ее использовал.

http://www.vogella.com/articles/EasyMock/article.html

8

Посмотрите на залп tests папку, там вы можете найти примеры.

MockCache.java 
MockHttpClient.java 
MockHttpStack.java 
MockHttpURLConnection.java 
MockNetwork.java 
MockRequest.java 
MockResponseDelivery.java 
+0

Ссылка на источник мертва. – Greyson

+0

@ Greyson обновленная ссылка. –

20

Я реализовал подкласс HttpStack имени FakeHttpStack что загрузить фальшивое тело ответа из локального файла, расположенного в Резе/сырье. Я сделал это для целей разработки, то есть я могу разработать что-то для нового API до того, как сервер будет готов, но вы можете узнать что-то (например, переопределить HttpStack # peformRequest и createEntity) здесь.

/** 
* Fake {@link HttpStack} that returns the fake content using resource file in res/raw. 
*/ 
class FakeHttpStack implements HttpStack { 
    private static final String DEFAULT_STRING_RESPONSE = "Hello"; 
    private static final String DEFAULT_JSON_RESPONSE = " {\"a\":1,\"b\":2,\"c\":3}"; 
    private static final String URL_PREFIX = "http://example.com/"; 
    private static final String LOGGER_TAG = "STACK_OVER_FLOW"; 

    private static final int SIMULATED_DELAY_MS = 500; 
    private final Context context; 

    FakeHttpStack(Context context) { 
     this.context = context; 
    } 

    @Override 
    public HttpResponse performRequest(Request<?> request, Map<String, String> stringStringMap) 
      throws IOException, AuthFailureError { 
     try { 
      Thread.sleep(SIMULATED_DELAY_MS); 
     } catch (InterruptedException e) { 
     } 
     HttpResponse response 
       = new BasicHttpResponse(new BasicStatusLine(HttpVersion.HTTP_1_1, 200, "OK")); 
     List<Header> headers = defaultHeaders(); 
     response.setHeaders(headers.toArray(new Header[0])); 
     response.setLocale(Locale.JAPAN); 
     response.setEntity(createEntity(request)); 
     return response; 
    } 

    private List<Header> defaultHeaders() { 
     DateFormat dateFormat = new SimpleDateFormat("EEE, dd mmm yyyy HH:mm:ss zzz"); 
     return Lists.<Header>newArrayList(
       new BasicHeader("Date", dateFormat.format(new Date())), 
       new BasicHeader("Server", 
         /* Data below is header info of my server */ 
         "Apache/1.3.42 (Unix) mod_ssl/2.8.31 OpenSSL/0.9.8e") 
     ); 
    } 

    /** 
    * returns the fake content using resource file in res/raw. fake_res_foo.txt is used for 
    * request to http://example.com/foo 
    */ 
    private HttpEntity createEntity(Request request) throws UnsupportedEncodingException { 
     String resourceName = constructFakeResponseFileName(request); 
     int resourceId = context.getResources().getIdentifier(
       resourceName, "raw", context.getApplicationContext().getPackageName()); 
     if (resourceId == 0) { 
      Log.w(LOGGER_TAG, "No fake file named " + resourceName 
        + " found. default fake response should be used."); 
     } else { 
      InputStream stream = context.getResources().openRawResource(resourceId); 
      try { 
       String string = CharStreams.toString(new InputStreamReader(stream, Charsets.UTF_8)); 
       return new StringEntity(string); 
      } catch (IOException e) { 
       Log.e(LOGGER_TAG, "error reading " + resourceName, e); 
      } 
     } 

     // Return default value since no fake file exists for given URL. 
     if (request instanceof StringRequest) { 
      return new StringEntity(DEFAULT_STRING_RESPONSE); 
     } 
     return new StringEntity(DEFAULT_JSON_RESPONSE); 
    } 

    /** 
    * Map request URL to fake file name 
    */ 
    private String constructFakeResponseFileName(Request request) { 
     String reqUrl = request.getUrl(); 
     String apiName = reqUrl.substring(URL_PREFIX.length()); 
     return "fake_res_" + apiName; 
    } 
} 

Чтобы использовать FakeHttpStack, вы просто должны передать его в RequestQueue. Я тоже переопределяю RequestQueue.

public class FakeRequestQueue extends RequestQueue { 
    public FakeRequestQueue(Context context) { 
     super(new NoCache(), new BasicNetwork(new FakeHttpStack(context))); 
    } 
} 

Хороший момент для этого подхода заключается в том, что он не требует значительных изменений в коде. Вам просто нужно переключить RequestQueue на FakeRequestQueue при тестировании. Таким образом, он может использоваться при приемочных испытаниях или системных испытаниях.

С другой стороны, для модульных испытаний может быть более компактным способом. Например, вы можете реализовать свой подкласс Request.Listener как отдельный класс, чтобы метод onResponse можно было легко протестировать. Я рекомендую вам более подробно рассказать о том, что вы хотите проверить или поместить фрагмент кода.

+0

Вы можете расширить Volley.java и переопределить newRequestQueue(), чтобы дать FakeRequestQueue. Если вы используете инъекцию зависимостей, вы можете просто ввести MyVolley.java вместо стандартного Volley.java, поэтому ваш код приложения не требует никаких изменений для тестирования. – Christine

+0

Можете ли вы посоветовать мне, как отмахиваться от ответа на запрос волейбольного модуля. – Dory

+0

Здравствуйте, я внедрил fakeRequestQueue, но он не дает никакого ответа. Взгляните здесь http://stackoverflow.com/questions/32623129/android-studio-unit-test-issues-in-writing-mock-tests-for-volley-request-fini – Dory

Смежные вопросы