Дразнить интерфейс против класса - PullRequest
0 голосов
/ 31 января 2019

У меня есть интерфейс, определенный следующим образом:

public interface HttpClient {
    public <T> UdemyResponse<T> get(Request request,
      JSONUnmarshaler<T> unmarshaller, Gson gson)
      throws UdemyException, IOException;
}

У меня есть класс, который реализует интерфейс:

public class OkHttp implements HttpClient {
public OkHttpClient client;

final Logger logger = LoggerFactory.getLogger(getClass());

public OkHttp() {
    this.client = new OkHttpClient();
}

@Override
public <T> UdemyResponse<T> get(Request request, JSONUnmarshaler<T> unmarshaller, Gson gson)
        throws UdemyException, IOException {

int status_code = 0;
        String next = null;
        String rawJSON = null;
        JsonElement jsonelement = null;

    Boolean retry = true;
    int attempts = 3;

    while ((attempts >= 0) && (retry) && status_code != 200) {
        try {
            Response response = this.client.newCall(request).execute();

            rawJSON = response.body().string();

            jsonelement = gson.fromJson(rawJSON, JsonElement.class);

            next = gson.fromJson(jsonelement.getAsJsonObject().get("next"), String.class);

            status_code = response.code();

            if (status_code == 401) {
                try {
                    logger.warn("token expired");
                    TimeUnit.SECONDS.sleep(5);
                    retry = true;
                    continue;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            if ((status_code / 100) == 5) {
                logger.warn("gateway error");
                retry = true;
                continue;
            }

        } catch (IOException e) {
            e.printStackTrace();
            // this exception will be propagated to the main method and handled there to exit the program,
            // this exception should end the program.
            throw e;

        }

        attempts -= 1;
        retry = false;

    }   
    if (status_code != 200) {
        throw new UdemyException();
    }

    return new UdemyResponse<T>(status_code, next, rawJSON,
            unmarshaller.fromJSON(gson, jsonelement.getAsJsonObject()));

}

Если я имитирую свой интерфейс, я могу написать контрольные примеры для получения(), но мой метод get () использует this.client, и мне нужно также смоделировать этот объект.

В этом случае, лучше ли имитировать объект OkHttp, а не интерфейс?

Ответы [ 2 ]

0 голосов
/ 31 января 2019

Отредактировано в ответ на изменение вопроса

Это ужасно: (status_code / 100).Там можно проверить реальный код состояния.

Вы должны сделать следующее:

  1. Создать макет OkHttpClient.
  2. Вставить макет в свой тестовый класс, используяотражение.
  3. протестируйте метод get.

Возможно, вы захотите изменить макет ОК в приведенном ниже коде, но вы можете просто использовать простой Mockito.издевается над всем.Вот пример кода:

public class TestOkHttp
{
  private static final String VALUE_JSON_STRING "some JSON string for your test";

  private OkHttp classToTest;

  @Mock
  private ClassWithExecute mockClassWithExecute;

  @Mock
  private OkHttpClient mockOkHttpClient;

  @Mock
  private Response mockResponse;

  @Mock
  private ResponseBodyClass mockResponseBodyClass;

  @Mock
  private Request mockRequest;

  private Gson testGson;

  @Test
  public void get_describeTheTest_expectedResults()
  {
    final JSONUnmarshaler<someclass> unmarshallerForThisTest = new JSONUnmarshaler<>()

    // setup the mocking functionality for this test.
    doReturn(desiredStatusCode).when(mockResponse).code();


    classToTest.get()
  }

  @Before
  public void preTestSetup()
  {
    MockitoAnnotations.initMocks(this);

    classToTest = new OkHttp();

    testGson = new Gson();

    doReturn(mockResponse).when(mockClassWithExecute).execute();

    doReturn(mockClassWithExecute).when(mockOkHttpClient).newCall(mockRequest);

    doReturn(mockResponseBodyClass).when(mockResponse).body();

    doReturn(VALUE_JSON_STRING).when(mockResponseBodyClass).string();

    ReflectionTestUtils.setField(classToTest,
      "client",
      mockOkHttpClient);
  }
}
0 голосов
/ 31 января 2019

Если вы пытаетесь протестировать get (), то вам не следует издеваться над этим методом, если вы это делаете, что вы тестируете?Вам нужно смоделировать другие зависимости get (), чтобы помочь вам проверить его изолированно.В этом случае, если this.client является зависимостью от get (), это то, что вам нужно смоделировать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...