Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Mockito-Unmocked方法无法返回对象本身_Java_Mockito_This - Fatal编程技术网

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

Java Mockito-Unmocked方法无法返回对象本身,java,mockito,this,Java,Mockito,This,我有一个Spring@RestController,它有一个apachecamel接口字段FluentProducerTemplate 我正在使用MockMvc测试控制器,并将FluentProducerTemplate作为模拟注入 我只想模拟一个方法-request(),并使用其他方法的实际实现 但是,我从未修改的方法中获得了NullPointerException。其他FluentProducerTemplate方法n

我有一个Spring
@RestController
,它有一个apachecamel接口字段
FluentProducerTemplate

我正在使用
MockMvc
测试控制器,并将
FluentProducerTemplate
作为模拟注入

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

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

  • 我认为mockito
    @Mock
    只模拟我指定的方法。其他方法使用原始实现。这是正确的说法吗
  • 我尝试了
    @Spy
    而不是
    @Mock
    ,结果得到了相同的错误
  • 当我模拟我使用的所有方法时,它就工作了,没有
    NullPointerException
  • 代码:

    @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())
    
        }
    
    }
    
    休息控制器:

    @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())
    
        }
    
    }
    
    测试:

    @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()
    时,测试才通过:

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

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

    1. <代码>间谍用于少数模拟,大部分是真实实现 如果只想模拟某些方法,或者调用真正的实现:

    FluentProducerTemplate producerTemplateMock = spy(FluentProducerTemplate.class);
    
    // Mock implementation
    doReturn(expectedResultSuccess).when(producerTemplateMock).request(any());
    
    // All other method call will use the real implementations
    
    2. <代码>模拟对于大多数模拟,很少有真正的实现
    如您所见,第二种方法更容易编写。然而,这取决于您的用例,哪种方法更合适。

    1st方法抛出
    NullPointerExecption
    。第二种方法-我得到了这个错误:
    org.mockito.exceptions.base.MockitoException:无法在java对象上调用抽象实方法!只有在模拟非抽象方法时才可能调用实方法//正确示例:when(mockOfConcreteClass.nonAbstractMethod()).thenCallRealMethod()此外,第二个选项
    然后调用realmethod
    中缺少括号。1)Nullpointer异常的堆栈跟踪是什么?2) 是的,如果您尝试使用的
    thenCallRealMethod
    方法是
    abstract
    ,则没有可用的实现,因此您会看到错误。要么提供一个默认实现,要么在测试中模拟它。1)模拟没有被注入,所以我从第一个
    withHeader
    调用中得到了
    NullPointerException
    。我试着用@Spy来代替。然后我又得到了
    NullPointerException
    ,但是是从第二个
    withHeader
    调用得到的。这意味着mock返回null,并且没有执行真正的方法。2)我在问题中注意到FluentProducerTemplate是一个接口。你说我必须嘲笑这种情况下的所有方法?我将尝试模拟接口的实现,并查看Spring是否知道如何使用
    @InjectMocks将其注入控制器
    Spring在模拟实现类而不是接口时未能注入模拟。我会嘲笑所有的方法。谢谢