Spring MockMVC,Spring 安全和 Mockito
Spring MockMVC, Spring security and Mockito
我想测试 Spring Boot
Rest 控制器,它使用 Spring security
保护,并在其中使用模拟。我试过使用 Mockito,但我认为任何模拟工具都应该可以解决问题。
为了在我的测试中启用 Spring 安全性,我首先执行以下操作:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Main.class)
@TestPropertySource(value="classpath:application-test.properties")
@WebAppConfiguration
@ContextConfiguration
public class MyTest{
protected MockMvc mockMvc;
@Autowired
private WebApplicationContext wac;
@Before
public void setUp(){
mockMvc = MockMvcBuilders
.webAppContextSetup(wac)
.apply(SecurityMockMvcConfigurers.springSecurity())
.build();
}
@Test
public void doTheTest(){
mockMvc.perform(post("/user/register")
.with(SecurityMockMvcRequestPostProcessors.csrf())
.content(someContent()));
}
}
到此为止,一切正常。
在这一步之后,我希望添加模拟来单独测试我的安全控制器。
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Main.class)
@TestPropertySource(value="classpath:application-test.properties")
@WebAppConfiguration
@ContextConfiguration
public class MyTest{
protected MockMvc mockMvc;
@Mock
private Myservice serviceInjectedInController;
@InjectMocks
private MyController myController;
@Autowired
private WebApplicationContext wac;
@Before
public void setUp(){
mockMvc = MockMvcBuilders
.webAppContextSetup(wac)
.apply(SecurityMockMvcConfigurers.springSecurity())
.build();
}
@Test
public void doTheTest(){
mockMvc.perform(post("/user/register")
.with(SecurityMockMvcRequestPostProcessors.csrf())
.content(someContent()));
}
}
不幸的是,模拟服务没有注入到控制器中,因为没有任何与 MockMVC 和模拟相关的东西,所以模拟没有注入到控制器中。
所以我尝试更改MockMVC的配置,如下:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Main.class)
@TestPropertySource(value="classpath:application-test.properties")
@WebAppConfiguration
@ContextConfiguration
public class MyTest{
protected MockMvc mockMvc;
@Mock
private Myservice serviceInjectedInController;
@InjectMocks
private MyController myController;
@Before
public void setUp(){
mockMvc = MockMvcBuilders
.standAloneSetup(myController)
.apply(SecurityMockMvcConfigurers.springSecurity())
.build();
}
@Test
public void doTheTest(){
mockMvc.perform(post("/user/register")
.with(SecurityMockMvcRequestPostProcessors.csrf())
.content(someContent()));
}
}
但在这种情况下,我还有另一个问题。 Spring 安全抱怨配置:
java.lang.IllegalStateException: springSecurityFilterChain cannot be null. Ensure a Bean with the name springSecurityFilterChain implementing Filter is present or inject the Filter to be used.
我没有其他想法来制作安全和嘲笑。任何的想法?还是我应该换一种方式?
谢谢。
默认情况下,集成会查找名称为 "springSecurityFilterChain" 的 bean。在所提供的示例中,使用了独立设置,这意味着 MockMvc
不会知道测试中提供的 WebApplicationContext
,因此无法查找 "springSecurityFilterChain" bean .
解决此问题的最简单方法是使用如下内容:
MockMvc mockMvc = MockMvcBuilders
// replace standaloneSetup with line below
.webAppContextSetup(wac)
.alwaysDo(print())
.apply(SecurityMockMvcConfigurers.springSecurity())
.build();
如果您真的想使用 standaloneSetup(实际上没有意义,因为您已经有一个 WebApplicationContext),您可以使用以下方法显式提供 springSecurityFilterChain:
@Autowired
FilterChainProxy springSecurityFilterChain;
@Before
public void startMocks(){
controller = wac.getBean(RecipesController.class);
MockMvc mockMvc = MockMvcBuilders
.standaloneSetup(controller)
.alwaysDo(print())
.apply(SecurityMockMvcConfigurers.springSecurity(springSecurityFilterChain))
.build();
MockitoAnnotations.initMocks(this);
}
我想测试 Spring Boot
Rest 控制器,它使用 Spring security
保护,并在其中使用模拟。我试过使用 Mockito,但我认为任何模拟工具都应该可以解决问题。
为了在我的测试中启用 Spring 安全性,我首先执行以下操作:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Main.class)
@TestPropertySource(value="classpath:application-test.properties")
@WebAppConfiguration
@ContextConfiguration
public class MyTest{
protected MockMvc mockMvc;
@Autowired
private WebApplicationContext wac;
@Before
public void setUp(){
mockMvc = MockMvcBuilders
.webAppContextSetup(wac)
.apply(SecurityMockMvcConfigurers.springSecurity())
.build();
}
@Test
public void doTheTest(){
mockMvc.perform(post("/user/register")
.with(SecurityMockMvcRequestPostProcessors.csrf())
.content(someContent()));
}
}
到此为止,一切正常。
在这一步之后,我希望添加模拟来单独测试我的安全控制器。
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Main.class)
@TestPropertySource(value="classpath:application-test.properties")
@WebAppConfiguration
@ContextConfiguration
public class MyTest{
protected MockMvc mockMvc;
@Mock
private Myservice serviceInjectedInController;
@InjectMocks
private MyController myController;
@Autowired
private WebApplicationContext wac;
@Before
public void setUp(){
mockMvc = MockMvcBuilders
.webAppContextSetup(wac)
.apply(SecurityMockMvcConfigurers.springSecurity())
.build();
}
@Test
public void doTheTest(){
mockMvc.perform(post("/user/register")
.with(SecurityMockMvcRequestPostProcessors.csrf())
.content(someContent()));
}
}
不幸的是,模拟服务没有注入到控制器中,因为没有任何与 MockMVC 和模拟相关的东西,所以模拟没有注入到控制器中。
所以我尝试更改MockMVC的配置,如下:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Main.class)
@TestPropertySource(value="classpath:application-test.properties")
@WebAppConfiguration
@ContextConfiguration
public class MyTest{
protected MockMvc mockMvc;
@Mock
private Myservice serviceInjectedInController;
@InjectMocks
private MyController myController;
@Before
public void setUp(){
mockMvc = MockMvcBuilders
.standAloneSetup(myController)
.apply(SecurityMockMvcConfigurers.springSecurity())
.build();
}
@Test
public void doTheTest(){
mockMvc.perform(post("/user/register")
.with(SecurityMockMvcRequestPostProcessors.csrf())
.content(someContent()));
}
}
但在这种情况下,我还有另一个问题。 Spring 安全抱怨配置:
java.lang.IllegalStateException: springSecurityFilterChain cannot be null. Ensure a Bean with the name springSecurityFilterChain implementing Filter is present or inject the Filter to be used.
我没有其他想法来制作安全和嘲笑。任何的想法?还是我应该换一种方式?
谢谢。
默认情况下,集成会查找名称为 "springSecurityFilterChain" 的 bean。在所提供的示例中,使用了独立设置,这意味着 MockMvc
不会知道测试中提供的 WebApplicationContext
,因此无法查找 "springSecurityFilterChain" bean .
解决此问题的最简单方法是使用如下内容:
MockMvc mockMvc = MockMvcBuilders
// replace standaloneSetup with line below
.webAppContextSetup(wac)
.alwaysDo(print())
.apply(SecurityMockMvcConfigurers.springSecurity())
.build();
如果您真的想使用 standaloneSetup(实际上没有意义,因为您已经有一个 WebApplicationContext),您可以使用以下方法显式提供 springSecurityFilterChain:
@Autowired
FilterChainProxy springSecurityFilterChain;
@Before
public void startMocks(){
controller = wac.getBean(RecipesController.class);
MockMvc mockMvc = MockMvcBuilders
.standaloneSetup(controller)
.alwaysDo(print())
.apply(SecurityMockMvcConfigurers.springSecurity(springSecurityFilterChain))
.build();
MockitoAnnotations.initMocks(this);
}