Mockito-Unmocked方法无法返回对象本身

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

我有一个Spring @RestController,它具有Apache Camel接口FluentProducerTemplate的字段。

我正在用MockMvc测试控制器,并以模拟方式注入FluentProducerTemplate

我只想模拟一个方法-request(),并使用其他方法的实际实现。

但是,我从未经模拟的方法中获得了NullPointerException。其他FluentProducerTemplate方法n ,其返回类型为FluentProducerTemplate。在实现中,它们返回this。模拟对象返回null。

  1. 我以为模仿@Mock仅模仿我指定的方法。其他方法使用原始实现。这是正确的说法吗?
  2. 我尝试使用@Spy而不是@Mock,并且遇到相同的错误。
  3. [当我嘲笑我使用的所有方法时,它将起作用并且没有NullPointerException

代码:

REST控制器:

@RestController
@RequestMapping("/v1/test”)

public class MyController {


@EndpointInject(uri = "direct:main")
private FluentProducerTemplate producerTemplate;

@RequestMapping(value = “/test2”, method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public MyResponse testRequest(
        @RequestHeader(“id”) String id,
        @RequestHeader(“context”) String context,
        @RequestBody RequestBody requestBody
) {
    MyResponse response = producerTemplate
            .withHeader(“id”, id)
            .withHeader(“context”, context)
            .withBody(requestBody)
            .request(MyResponse.class);
    return response;
}

测试:

@RunWith(MockitoJUnitRunner.class)
public class MyControllerTest {

    private MockMvc mockMvc;

    @Mock
    private FluentProducerTemplate producerTemplateMock;

    @InjectMocks
    private MyControllerTest myController;

    private static MyResponse expectedResultSuccess;

    private static String requestString;

    private static HttpHeaders allRequestHeaders;

    @BeforeClass
    public static void setup() {

        allRequestHeaders = new HttpHeaders();
        allRequestHeaders.set(“id”, “123”);
        allRequestHeaders.set(“context”, “ABCD1234”);
        allRequestHeaders.set(“Content-Type”, “application/json”);

        expectedResultSuccess =  new MyResponse(“test”);

        requestString = “request”BodyText;

    }

    @Before
    public void init() {

        mockMvc = MockMvcBuilders.standaloneSetup(myController).build();

        when(producerTemplateMock.request(any())).thenReturn(expectedResultSuccess);

    }

    @Test
    public void testSuccess() throws Exception {

        mockMvc.perform(post(“/v1/test/test2)
                .headers(allRequestHeaders)
                .content(requestString))
                .andExpect(status().isOk())

    }

}

仅当我将以下内容添加到init()时,测试通过:

  when(producerTemplateMock.withHeader(any(), any())).thenReturn(producerTemplateMock);
  when(producerTemplateMock.withBody(any())).thenReturn(producerTemplateMock);

我的主要问题是-为什么我必须模拟所有方法?我更喜欢使用withHeader()withBody()的原始实现,并且仅模拟request()

java mockito this
1个回答
1
投票

您想要所谓的局部模拟。根据您是要设置大多数模拟还是大部分调用真实的实现,有不同的首选方法。

1。 spy少量模拟,大部分为实际实现

如果只想模拟某些方法,否则调用真正的实现:

FluentProducerTemplate producerTemplateMock = spy(FluentProducerTemplate.class);

// Mock implementation
doReturn(expectedResultSuccess).when(producerTemplateMock).request(any());

// All other method call will use the real implementations

2。 mock主要用于模拟,很少使用实际实现

FluentProducerTemplate producerTemplateMock = mock(FluentProducerTemplate.class);

// Mock methods
when(producerTemplateMock.request(any())).thenReturn(expectedResultSuccess);

// tell mockito to call the real methods
when(producerTemplateMock.withHeader(any(), any())).thenCallRealMethod;
when(producerTemplateMock.withBody(any())).thenCallRealMethod();

如您所见,第二种方法是编写更多样板。但是,这取决于您的用例,哪种方法更合适。

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