2

I have this test:

@ExtendWith(SpringExtension.class)
@WebMvcTest(AuthController.class)
@TestPropertySource("classpath:application.properties")
class AuthControllerTest {

    @Autowired
    private MockMvc mvc;

    @Autowired
    AuthTokenFilter authTokenFilter;

    @MockBean
    AuthEntryPointJwt authEntryPointJwt;

    @MockBean
    JwtUtils jwtUtils;

    @Autowired
    private ObjectMapper objectMapper;

    @MockBean
    UserDetailsServiceImpl userDetailsServiceImpl;

    @MockBean
    AuthenticationManager authenticationManager;

    @MockBean
    Authentication authentication;

    @MockBean
    SecurityContext securityContext;

    @Test
    void test1withEnabledTrue() {
    }

    @Test
    void test2WithEnabledTrue() {
    }

    @Test
    void cannotRegisterUserWhenRegistrationsAreDisabled() throws Exception {
        
        var userToSave = validUserEntity("username", "password");
        var savedUser = validUserEntity("username", "a1.b2.c3");

        when(userDetailsServiceImpl.post(userToSave)).thenReturn(savedUser);

        mvc.perform(post("/api/v1/auth/register/").contentType(MediaType.APPLICATION_JSON)
                .content(objectMapper.writeValueAsBytes(userToSave))).andExpect(status().isCreated())
        .andExpect(jsonPath("$.status", is("registrations are disabled")));
    }

    private static UsersEntity validUserEntity(String username, String password) {
        return UsersEntity.builder().username(username).password(password).build();
    }

}

And this is the relevant part in Controller (Class Under Test):

@Value("${app.enableRegistration}")
private Boolean enableRegistration;

private Boolean getEnableRegistration() {
    return this.enableRegistration;
}

@PostMapping("/register")
@ResponseStatus(HttpStatus.CREATED)
public Map<String, String> post(@RequestBody UsersDTO usersDTO) {

    Map<String, String> map = new LinkedHashMap<>();

    if (getEnableRegistration()) {
        [...]
        map.put("status", "ok - new user created");
        return map;
    }
    map.put("status", "registrations are disabled");
    return map;

}

I have this application.properties under src/test/resources and I need to override it, only for my single test named cannotRegisterUserWhenRegistrationsAreDisabled

app.enableRegistration=true

Probably I could use another file "application.properties" and another class test, but I'm looking for a smarter solution.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
sineverba
  • 5,059
  • 7
  • 39
  • 84

2 Answers2

3

You can simply configure the inline properties of @TestPropertySource which has a higher precedence than the properties loaded from locations/ value :

@WebMvcTest(AuthController.class)
@TestPropertySource(locations = "classpath:application.properties" ,properties="app.enableRegistration=true" )
class AuthControllerTest {


}

All inline properties specified in the properties will override those specified in the application.properties

Ken Chan
  • 84,777
  • 26
  • 143
  • 172
  • It works... But I needed to create another Controller. Is there something to change an application property at test level and not at class level? – sineverba Feb 19 '22 at 14:19
  • 1
    it is still not possible with `@TestPropertySource`(see [this](https://github.com/spring-projects/spring-framework/issues/18951)) – Ken Chan Feb 19 '22 at 15:28
  • why not just `@WebMvcTest(AuthController.class,,properties = {"app.enableRegistration=true"})` ? – user1767316 Aug 04 '23 at 08:17
0

I think what you are looking for is the @TestProperty annotation, which was an answer of a question on Stackoverflow here. However this only works on class level, not for one test only.

You probably need to make a new test class and add the tests where it the value needs to be false.

Doompickaxe
  • 194
  • 1
  • 9