У меня есть простое веб-приложение:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@RestController
public class SimpleController {
@Autowired
private String sayHello;
@GetMapping("/hello")
public String hello() {
return sayHello;
}
}
@Configuration
public class StringConfig {
@Bean
public String sayHelloWorld() {
return "Hello, World!";
}
}
И добавить тесты:
//This is abstarct class for test.
@WebAppConfiguration
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = Application.class)
public abstract class AbstractTestClass {
@Autowired
private WebApplicationContext webApplicationContext;
protected MockMvc mockMvc;
@Before
public void init() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
}
//This is custom configuration for bean "sayHello".
@Configuration
public class ConfigurationForTest {
@Bean
public String sayHello() {
return "Hello, Test1!";
}
}
//This test loads custom config with ApplicationContext.
@ContextConfiguration(classes = ConfigurationForTest.class)
public class SimpleControllerTest1 extends AbstractTestClass {
//Checks that enpoind return expected reponse.
@Test
public void shouldReturnHelloTest1() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/hello"))
.andExpect(MockMvcResultMatchers.content().string("Hello, Test1!"));
}
}
//This test don't loads custom configuration and works on default ApplicationContext.
public class SimpleControllerTest2 extends AbstractTestClass {
//Checks that enpoind return expected reponse.
@Test
public void shouldReturnHelloWorld() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/hello"))
.andExpect(MockMvcResultMatchers.content()
.string("Hello,World!"));
}
}
Этот тест не проходит с:
Failed to load ApplicationContext
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [org.springframework.cloud.context.environment.EnvironmentManager@1ed864e4] with key 'environmentManager'; nested exception is javax.management.InstanceAlreadyExistsException: org.springframework.cloud.context.environment:name=environmentManager,type=EnvironmentManager
Caused by: javax.management.InstanceAlreadyExistsException: org.springframework.cloud.context.environment:name=environmentManager,type=EnvironmentManager
Чем это вызвано?Это не ясно для меня.Я знаю, что могу добавить @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
или использовать другую аннотацию @WebMvcTest
, @SpringBootTest + @AutoConfigureMockMvc
.Но я хочу знать, почему это происходит и как напрямую загружать весь контекст приложения, используя этот подход, если мое приложение будет более сложным?
В чем разница между @ContextConfiguration(classes=Application.class)
и @SpringBootTest
.Почему эта ошибка не возникает при использовании @SpringBootTest
?С @SpringBootTest
ApplciationContext также загружается дважды, но тесты проходят успешно.