为什么我的Integration Test试图设置一个新的jetty实例?

时间:2017-01-05 17:59:32

标签: java spring spring-boot mockito integration-testing

我有一个包含3个集成测试类的项目:A,B和C. 我对代码进行了更改,作为这些更改的一部分,我添加了一个@MockBean来测试类A.

这是一个由每个Integration Test类扩展的类:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = MyApplication.class, webEnvironment = RANDOM_PORT)
@TestPropertySource(locations = "classpath:application-test.yml")
@ActiveProfiles(profiles = {"default", "test"})
public abstract class IntegrationTest {

    @Value("${local.server.port}")
    private int serverPort;

    @Autowired
    private ObjectMapper objectMapper;

    @Before
    public void setUpIntegrationTest() {
        RestAssured.port = serverPort;
        RestAssured.config = RestAssuredConfig.config()
                .logConfig(LogConfig.logConfig()
                        .enableLoggingOfRequestAndResponseIfValidationFails()
                        .enablePrettyPrinting(true))
                .objectMapperConfig(objectMapperConfig()
                        .jackson2ObjectMapperFactory((cls, charset) -> objectMapper)
                        .defaultObjectMapperType(ObjectMapperType.JACKSON_2))
                .jsonConfig(jsonConfig().numberReturnType(BIG_DECIMAL))
                .redirect(new RedirectConfig().followRedirects(false));
    }
}

现在进行具体的测试课程:

import org.springframework.boot.test.mock.mockito.MockBean;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doNothing;

public class TestClassA extends IntegrationTest {
    @MockBean
    private SomeBean foo;

    @Before
    @Override
    public void setUpIntegrationTest() {
        super.setUpIntegrationTest();
        doNothing().when(foo).fooMethod(any(SomeClass.class), any(SomeOtherClass.class));
    }

    @Test
    public void testCaseX() {
        given()
            .body("{\"foo\": \"bar\"}")
        .when()
            .post("/some/path/")
        .then()
            .statusCode(OK.value());
    }
}

我试图以三种不同的方式运行测试:

  1. 使用模拟的bean仅运行测试类A.所有测试都通过了。
  2. 构建运行所有测试类的项目。测试类B和C通过,但在尝试启动jetty实例时,在应用程序上下文加载期间A失败,因为该地址已在使用中而失败。
  3.   

    引起:org.springframework.beans.BeanInstantiationException:无法实例化[io.github.azagniotov.stubby4j.server.StubbyManager]:工厂方法' stubby'抛出异常;嵌套异常是java.net.BindException:地址已在使用中   引起:java.net.BindException:地址已在使用中

    1. 删除模拟的bean,然后构建项目。测试类B和C通过。测试类A成功加载应用程序上下文,但某些测试失败(由于模拟提供的缺失行为)。
    2. Jetty是Stubby4J的一部分,它以下列方式实例化为配置bean:

      @Configuration
      public class StubbyConfig {
      
          @Bean
          public StubbyManager stubby(final ResourceLoader resourceLoader) throws Exception {
      
              Resource stubbyFile = resourceLoader.getResource("classpath:stubs/stubby.yml");
      
              if (stubbyFile.exists()) {
                  Map<String, String> stubbyConfig = Maps.newHashMap();
                  stubbyConfig.put("disable_admin_portal", null);
                  stubbyConfig.put("disable_ssl", null);
      
                  File configFile = stubbyFile.getFile();
                  Future<List<StubHttpLifecycle>> stubLoadComputation =
                          ConcurrentUtils.constantFuture(new YAMLParser().parse(configFile.getParent(), configFile));
      
                  StubbyManager stubbyManager = new StubbyManagerFactory()
                          .construct(configFile, stubbyConfig, stubLoadComputation);
                  stubbyManager.startJetty();
      
                  return stubbyManager;
              } else {
                  throw new FileNotFoundException("Could not load stubby.yml");
              }
          }
      }
      

      我以两种不同的方式进行了一些调试,在stubbyManager.startJetty();行中设置了一个断点:

      1. 仅运行测试类A.执行仅在断点处停止一次。
      2. 使用其他测试类运行测试类A(例如,B)。执行仅对B停止一次,对A停止两次。第二次因上述错误而失败。
      3. 同样,如果我删除模拟的bean并运行多个测试类,则每个测试类只会在该行停止执行一次。
      4. 我的问题显然是:为什么MockedBean注释会导致这种行为,我该如何避免它呢?

        提前致谢。

        当前项目设置:

        • Spring Boot版本1.4.2.RELEASE
        • Stubby4j版本4.0.4

1 个答案:

答案 0 :(得分:0)

我刚刚开始使用Jetty:

if(!stubbyManager.statuses().contains(""Stubs portal configured at")
    stubbyManager.startJetty();
else
    stubbyManager.joinJetty();

如果您找到更好的解决方案,请告诉我