Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.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
Unit testing 在单元测试方法中更改应用程序属性值_Unit Testing_Spring Boot - Fatal编程技术网

Unit testing 在单元测试方法中更改应用程序属性值

Unit testing 在单元测试方法中更改应用程序属性值,unit-testing,spring-boot,Unit Testing,Spring Boot,我的RESTAPI在POST请求中生成密码并将其存储在DB中。出于开发目的,当application.properties文件中的development.mode标志设置为true时,我想将其放在响应中 我想测试这个控制器,并检查如果标志为true,则密码在响应中,如果为false,则密码不在响应中 我想知道是否以及如何从每个测试方法中动态设置这个属性值 这是我的控制器: @RestController public class PasswordController { @Value("$

我的RESTAPI在POST请求中生成密码并将其存储在DB中。出于开发目的,当application.properties文件中的development.mode标志设置为true时,我想将其放在响应中

我想测试这个控制器,并检查如果标志为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);
  }    
}
是否有可能在每个测试方法中设置@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注释中使用了我的测试类。

您可以创建另一个
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。

谢谢您的回复。我不确定是否理解:使用您的解决方案,我如何在同一个测试类中有两个单元测试,一个测试development.mode=true,另一个测试为false?我的理解是,我必须创建两个类,包含两个applicationContext文件,我错了吗?啊,是的,在这种情况下,您必须创建两个类。另一种选择是使用ReflectionTestUtils,但从applicationContext获取控制器,而不是直接实例化。或者您可以只为字段提供一个setter谢谢,它与应用程序上下文和反射很好地配合
@RunWith(SpringRunner.class)
@WebMvcTest(PasswordControllerTest.class)
@ContextHierarchy({
    @ContextConfiguration(locations = "path_to applicationContext-tests.xml")
})
public class PasswordControllerTest extends OtpTest {