代码之家  ›  专栏  ›  技术社区  ›  user1050619

模拟接口与类

  •  0
  • user1050619  · 技术社区  · 7 年前

    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()方法编写测试用例,但是我的get()方法使用this.client,我还需要模拟该对象。

    2 回复  |  直到 7 年前
        1
  •  0
  •   Kevin Hooke    7 年前

    如果您试图测试get(),那么不应该模拟该方法,如果您这样做了,您要测试的是什么?您需要模拟get()的其他依赖项,以帮助您单独测试它。在本例中,如果this.client是get()的依赖项,则需要模拟它。

        2
  •  0
  •   DwB    7 年前

    根据问题更改进行编辑

    这太可怕了: (status_code / 100) 测试那里的真实状态代码。

    您应该执行以下操作:

    1. OkHttpClient .
    2. 使用反射将模拟注入测试类。
    3. 测试 get

    您可能需要更改下面代码中对ok的模拟, 但是您应该能够对所有内容使用简单的Mockito mock。 下面是一些示例代码:

    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);
      }
    }