Mockito Spring 数据网络支持
Mockito Spring Data Web Support
我是 Mockito 的新手,在 Spring 数据 Web 支持方面有一些问题。
我的控制器中有以下功能。
@DeleteMapping("/")
public MyObject delete(@RequestParam("id")MyObject object){
...do something
}
描述了这里发生的事情(在实际用例中)here。
问题是,当我在单元测试中使用 MockMvc 和 Mockito 时,没有数据库,也没有持久性存储库。我怎样才能让 Spring 使用 mockRepository 将 /?id=1
中移交的 ID 替换为我选择的 MyObject 实例。
这是测试的样子:
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import com.mine.OrgUnitController;
import com.mine.OrgUnitService;
@RunWith(SpringJUnit4ClassRunner.class)
public class OrgUnitControllerTest2 {
private MockMvc mockMvc;
@Mock
SomeService someService;
@InjectMocks
MyController controller;
@Before
public void init() {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
}
@Test
public void test_delete() throws Exception {
mockMvc.perform(delete("/?id=1")).andExpect(status().isOk());
}
}
非常感谢任何帮助。
要return一个给定id的MyObject,你可以使用when(….).thenReturn(….)
。因此,当您在 SomeService 中有一个通过 id 查找 MyObject 的方法时,您可以存根这个和 return 值。
// When the get method is called, it will return MyObject
when(someService.get(id)).thenReturn(new MyObject());
我想如果你只使用 Mockito
而不是 Mockito
+ MockMvc
.
对你来说会更容易
你可以这样做:
@RunWith(SpringJUnit4ClassRunner.class)
public class OrgUnitControllerTest2 {
@Mock
SomeService someService;
@InjectMocks
MyController controller;
@Before
public void init() {
MockitoAnnotations.initMocks(this);
}
@Test
public void test_delete() throws Exception {
//given
given(someService.delete(1)).willReturn(true); //or successful response
//when
MyObject response = controller.delete(1);
//then
assertTrue(OK, response.getStatus())
}
}
好吧,解决方案非常简单,只花了我 2 天的时间。 ;)
为了使 SpringDataWebSupport 工作 spring 使用 org.springframework.data.repository.support.DomainClassConverter
这是一个 ConversionService。接下来要知道的是 MockMvc 通过 setConversionService()
接受 ConversionService。所以剩下要做的唯一一件事就是编写我自己的 ConversionService,这实际上非常简单。我这样扩展 DefaultFormattingConversionService
:
public class MockSpringDataWebSupport extends DefaultFormattingConversionService {
/**
* @param converters {@link Converter Converters} that shall be added to this {@link ConversionService}
*/
@SafeVarargs
public MockSpringDataWebSupport(Converter<? extends Object, ? extends Object>... converters) {
for (Converter<? extends Object, ? extends Object> converter : converters) {
this.addConverter(converter);
}
}
}
这样我就可以交出任何符合我测试需要的自定义转换器。在这种特殊情况下,我使用了:
mockMvc = MockMvcBuilders.standaloneSetup(controller)
.setConversionService(new MockSpringDataWebSupport(new Converter<String, MyObject>() {
@Override
public OrgUnit convert(String source) {
return new MyObject();
}
})).build();
它奏效了。
您可能需要在 MockMvc
对象中设置 setCustomArgumentResolvers
,如下所示:
@Before
public void init() {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders
.standaloneSetup(controller)
.setCustomArgumentResolvers(new HandlerMethodArgumentResolver(){...})
.build();
}
您需要弄清楚哪个 class 正在实现 HandlerMethodArgumentResolver
,然后在上面的 init()
方法中使用它。
您可以查看 this 资源。
How can i make Spring use a mockRepository to replace the id handed over in /?id=1 by a MyObject-instance of my choice
您可以通过模拟 WebConversionService
来做到这一点,这将避免通过实体存储库 findById
进行数据库查找。您还可以设置要使用的实例,而无需从数据库中获取实例。有关如何模拟此服务的更多详细信息,请查看 .
我是 Mockito 的新手,在 Spring 数据 Web 支持方面有一些问题。
我的控制器中有以下功能。
@DeleteMapping("/")
public MyObject delete(@RequestParam("id")MyObject object){
...do something
}
描述了这里发生的事情(在实际用例中)here。
问题是,当我在单元测试中使用 MockMvc 和 Mockito 时,没有数据库,也没有持久性存储库。我怎样才能让 Spring 使用 mockRepository 将 /?id=1
中移交的 ID 替换为我选择的 MyObject 实例。
这是测试的样子:
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import com.mine.OrgUnitController;
import com.mine.OrgUnitService;
@RunWith(SpringJUnit4ClassRunner.class)
public class OrgUnitControllerTest2 {
private MockMvc mockMvc;
@Mock
SomeService someService;
@InjectMocks
MyController controller;
@Before
public void init() {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
}
@Test
public void test_delete() throws Exception {
mockMvc.perform(delete("/?id=1")).andExpect(status().isOk());
}
}
非常感谢任何帮助。
要return一个给定id的MyObject,你可以使用when(….).thenReturn(….)
。因此,当您在 SomeService 中有一个通过 id 查找 MyObject 的方法时,您可以存根这个和 return 值。
// When the get method is called, it will return MyObject
when(someService.get(id)).thenReturn(new MyObject());
我想如果你只使用 Mockito
而不是 Mockito
+ MockMvc
.
你可以这样做:
@RunWith(SpringJUnit4ClassRunner.class)
public class OrgUnitControllerTest2 {
@Mock
SomeService someService;
@InjectMocks
MyController controller;
@Before
public void init() {
MockitoAnnotations.initMocks(this);
}
@Test
public void test_delete() throws Exception {
//given
given(someService.delete(1)).willReturn(true); //or successful response
//when
MyObject response = controller.delete(1);
//then
assertTrue(OK, response.getStatus())
}
}
好吧,解决方案非常简单,只花了我 2 天的时间。 ;)
为了使 SpringDataWebSupport 工作 spring 使用 org.springframework.data.repository.support.DomainClassConverter
这是一个 ConversionService。接下来要知道的是 MockMvc 通过 setConversionService()
接受 ConversionService。所以剩下要做的唯一一件事就是编写我自己的 ConversionService,这实际上非常简单。我这样扩展 DefaultFormattingConversionService
:
public class MockSpringDataWebSupport extends DefaultFormattingConversionService {
/**
* @param converters {@link Converter Converters} that shall be added to this {@link ConversionService}
*/
@SafeVarargs
public MockSpringDataWebSupport(Converter<? extends Object, ? extends Object>... converters) {
for (Converter<? extends Object, ? extends Object> converter : converters) {
this.addConverter(converter);
}
}
}
这样我就可以交出任何符合我测试需要的自定义转换器。在这种特殊情况下,我使用了:
mockMvc = MockMvcBuilders.standaloneSetup(controller)
.setConversionService(new MockSpringDataWebSupport(new Converter<String, MyObject>() {
@Override
public OrgUnit convert(String source) {
return new MyObject();
}
})).build();
它奏效了。
您可能需要在 MockMvc
对象中设置 setCustomArgumentResolvers
,如下所示:
@Before
public void init() {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders
.standaloneSetup(controller)
.setCustomArgumentResolvers(new HandlerMethodArgumentResolver(){...})
.build();
}
您需要弄清楚哪个 class 正在实现 HandlerMethodArgumentResolver
,然后在上面的 init()
方法中使用它。
您可以查看 this 资源。
How can i make Spring use a mockRepository to replace the id handed over in /?id=1 by a MyObject-instance of my choice
您可以通过模拟 WebConversionService
来做到这一点,这将避免通过实体存储库 findById
进行数据库查找。您还可以设置要使用的实例,而无需从数据库中获取实例。有关如何模拟此服务的更多详细信息,请查看