我的REST API在POST请求中生成密码并将其存储在数据库中。出于开发目的,当application.properties文件中的development.mode标志设置为true时,我想将其放入响应中。
我想测试这个控制器,并检查如果标志为真,则密码在响应中,如果为false,则密码不是。
我想知道是否以及如何从每个测试方法动态设置此属性值。
这是我的控制者:
@RestController
public class PasswordController {
@Value("${development.mode}")
private boolean isDevelopmentMode;
@RequestMapping(value = "/new", method = RequestMethod.POST)
public ResponseEntity<String> generatePassword(@RequestParam(USERNAME_PARAM) String username) {
String password = manager.generatePassword();
String body = "";
if (isDevelopmentMode) {
body = "New password: " + password;
}
return new ResponseEntity<>(body, HttpStatus.OK);
}
}
我已经看过使用@PropertySource定义不同属性文件进行测试的文档,但它在类级别,我想避免创建一个不同的文件来改变标志。
我还看到帖子说你可以使用ReflectionUtils.setField来改变私有字段的值,但为此我必须明确地实例化我的控制器,因此在自动连接字段中存在一些问题。我试过这个:
@RunWith(SpringRunner.class)
@WebMvcTest(PasswordControllerTest.class)
public class PasswordControllerTest extends OtpTest {
@Autowired
private MockMvc mockMvc;
@Test
public void newRoute_developmentModeIsFalse_responseBodyIsEmpty() throws Exception {
PasswordController controller = new PasswordController();
ReflectionTestUtils.setField(controller, "isDevelopmentMode", false);
MockMvc mvc = MockMvcBuilders.standaloneSetup(new PasswordController()).build();
given(manager.generatePassword(any(String.class))).willReturn("123456");
mvc.perform(post("/new").param(PasswordController.USERNAME_PARAM, "test_user")).andExpect(status().isOk()).andExpect(content().string(""));
}
}
是否有可能在每个测试方法中设置@Value字段的值?我应该重构我的代码以不同方式访问它吗?
解 感谢Borys Zibrov,它使用了以下代码:
@RunWith(SpringRunner.class)
@WebMvcTest(PasswordController.class)
public class PasswordControllerTest extends OtpTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private WebApplicationContext applicationContext;
@Test
public void newRoute_developmentModeIsTrue_passwordIsInTheResponseBody() throws Exception {
PasswordController controller = applicationContext.getBean(PasswordController.class);
ReflectionTestUtils.setField(controller, "isDevelopmentMode", true);
given(manager.generatePassword(any(String.class))).willReturn("123456");
mockMvc.perform(post("/new").param(PasswordController.USERNAME_PARAM, "test_user")).andExpect(status().isOk())
.andExpect(content().string("New password: 123456"));
}
}
从应用程序上下文中获取我的控制器bean起初并不起作用,因为在我以前的代码中我在WebMvcTest注释中使用了我的测试类。
答案 0 :(得分:0)
您可以创建另一个applicationContext-tests.xml
,通过以下方式将其连接到您的测试:
@RunWith(SpringRunner.class)
@WebMvcTest(PasswordControllerTest.class)
@ContextHierarchy({
@ContextConfiguration(locations = "path_to applicationContext-tests.xml")
})
public class PasswordControllerTest extends OtpTest {
并覆盖该属性development.mode
。
您也可以坚持使用ReflectionTestUtils
,而不是直接实例化,而是使用spring为您构造的applicationContext中的bean,然后在该bean上设置属性。
或者您可以为该字段提供一个setter。