Java Mockito-Unmocked方法无法返回对象本身
我有一个SpringJava Mockito-Unmocked方法无法返回对象本身,java,mockito,this,Java,Mockito,This,我有一个Spring@RestController,它有一个apachecamel接口字段FluentProducerTemplate 我正在使用MockMvc测试控制器,并将FluentProducerTemplate作为模拟注入 我只想模拟一个方法-request(),并使用其他方法的实际实现 但是,我从未修改的方法中获得了NullPointerException。其他FluentProducerTemplate方法n
@RestController
,它有一个apachecamel接口字段FluentProducerTemplate
我正在使用MockMvc
测试控制器,并将FluentProducerTemplate
作为模拟注入
我只想模拟一个方法-request()
,并使用其他方法的实际实现
但是,我从未修改的方法中获得了NullPointerException
。其他FluentProducerTemplate
方法n ,其返回类型为FluentProducerTemplate
。在实现中,它们返回this
。模拟对象返回null
@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在模拟实现类而不是接口时未能注入模拟。我会嘲笑所有的方法。谢谢