是否可以初始化模拟对象中的某些字段

Is it possible to initialize some of the fields in a mock object

我有一段代码无法通过测试正确覆盖。 我正在使用 Mockito 库。 而我在开始测试的那一刻遇到了困难

下面是测试代码:

@Test
public void testLoadCar() {
    when(remoteService.loadData()).thenReturn(new DataResult<DataCar>("", "", new DataCar()));
    when(dataResult.hasError()).thenReturn(true);
    when(dataResult.response.hasHeaders()).thenReturn(true);
    requestNetwork = new RequestNetwork(remoteService);
    Response<DataCar> response = requestNetwork.load(request);
}

这些是测试中的对象class:remoteService、dataResult、request。

我担心我尝试实现 when 方法的时刻:

when(dataResult.response.hasHeaders()).thenReturn(true);

我想知道这样的录音是否可行。 如果不行,那我们怎么处理这一刻:

protected Response createResponse(DataResult<T> dataResult) {
    if (dataResult.hasError()  || !dataResult.response.hasHeaders()) {
        return dataResult.getErrorMessage());
    } else {
        return Response.data(dataResult.value);
    }
}

这是被测系统 (SUT) 上的一种方法,它具有 createResponse() 方法。此方法包含对 DataResult 对象的 mock 方法的调用。 实现dataResult.hasError()我搞定了:

when (dataResult.hasError ()). thenReturn (true);

然后用! DataResult.response.hasHeaders() 我有问题。因为我不知道如何替换我需要的值。

并非所有被测对象与之交互的对象都需要模拟。 请记住,您也可以使用 POJO。

DataResult 看起来非常适合 POJO。 如果您可以创建具有所需状态和行为的 POJO,那么使用模拟对象将一无所获。

查看 posted 代码,看起来很容易创建:

new DataResult<DataCar>("", "", new DataCar())

最重要的是:

我觉得你的代码很可疑。

  • 存根时 remoteService.loadData() 您创建了 DataResult
  • 的新实例
  • 随后,您对 dataResult 进行了一些调用,这不是从 remoteService.loadData()
  • 返回的对象

并回答原文post:

您可以在模拟上设置字段(如果访问修饰符允许则直接设置,否则通过反射设置)。请注意,这是对 mock 的非常不合常理且令人惊讶的使用。

class A {
    B b;
}

class B {
    boolean hasHeaders() {
        return true;
    }
}

@ExtendWith(MockitoExtension.class)
public class AAATest {

    @Mock
    A aMock;

    @Mock
    B bMock;

    @BeforeEach
    void setupMocks() {
        aMock.b = bMock;
    }

    @Test
    void testFieldInMockIsInitialized() {
        Assertions.assertEquals(bMock, aMock.b);
    }
}