InstanceAlreadyExistsException для EnvironmentManager при попытке запустить приложение Spring Boot в обычном тесте Spring - PullRequest
0 голосов
/ 08 февраля 2019

У меня есть простое веб-приложение:

@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 также загружается дважды, но тесты проходят успешно.

...