Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.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
Java 为什么我的集成测试试图设置一个新的jetty实例?_Java_Spring Boot_Mockito_Integration Testing_Stubby4j - Fatal编程技术网

Java 为什么我的集成测试试图设置一个新的jetty实例?

Java 为什么我的集成测试试图设置一个新的jetty实例?,java,spring-boot,mockito,integration-testing,stubby4j,Java,Spring Boot,Mockito,Integration Testing,Stubby4j,我有一个包含3个集成测试类的项目:a、B和C。 我对代码进行了更改,作为这些更改的一部分,我添加了一个@MockBean来测试类a 下面是一个由每个集成测试类扩展的类: @RunWith(SpringRunner.class) @SpringBootTest(classes = MyApplication.class, webEnvironment = RANDOM_PORT) @TestPropertySource(locations = "classpath:application-test

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

下面是一个由每个集成测试类扩展的类:

@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());
    }
}
现在,对于一个具体的测试类:

@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());
    }
}
我尝试过以三种不同的方式运行测试:

  • 仅使用模拟bean运行测试类A。所有测试都通过了
  • 构建运行所有测试类的项目。测试类B和C通过,但A在尝试启动jetty实例时在应用程序上下文加载期间失败,并且由于地址已在使用而失败
  • 原因:org.springframework.beans.beanstanitiationException:未能实例化[io.github.azagniotov.stubby4j.server.StubbyManager]:工厂方法“stubby”引发异常;嵌套异常为java.net.BindException:地址已在使用中 原因:java.net.BindException:地址已在使用中

  • 移除模拟bean,并构建项目。B级和C级考试合格。测试类A成功地加载了应用程序上下文,但一些测试失败(由于模拟所给出的行为缺失)
  • 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");
            }
        }
    }
    
    @配置
    公共类StubbyConfig{
    @豆子
    公共StubbyManager stubby(最终资源加载程序ResourceLoader)引发异常{
    Resource stubbyFile=resourceLoader.getResource(“类路径:stubs/stubby.yml”);
    if(stubbyFile.exists()){
    Map stubbyConfig=Maps.newHashMap();
    stubbyConfig.put(“禁用管理员门户”,null);
    stubbyConfig.put(“禁用ssl”,null);
    File configFile=stubbyFile.getFile();
    未来负荷计算=
    ConcurrentUtils.constantFuture(新的YAMLParser().parse(configFile.getParent(),configFile));
    StubbyManager StubbyManager=新建StubbyManagerFactory()
    .construct(configFile、stubbyConfig、stubLoadComputation);
    stubbyManager.startJetty();
    返回stubbyManager;
    }否则{
    抛出新的FileNotFoundException(“无法加载stubby.yml”);
    }
    }
    }
    
    我用两种不同的方式进行了一些调试,在
    stubbyManager.startJetty()行中放置了一个断点

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

    提前谢谢

    当前项目设置:

    • Spring Boot版本1.4.2.0发布
    • Stubby4j版本4.0.4

    我刚启动Jetty,但还没有完成:

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

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

    “我在测试类a时添加了@MockedBean”我在测试中看不到任何
    @injectmock
    。我遗漏了什么吗?遗漏了一些注释,是的。但是不需要
    @InjectMocks
    。根据Spring文档,您可以在Spring的文档@user2004685中看到一个示例-当MockBean用于字段时,以及在应用程序上下文中注册时,模拟也将被注入到field@DavidWallace但在这种情况下,我们是否应该为具有预期行为的测试类使用不同的
    ApplicationContext
    ?如果我错了,请纠正我,因为这对我来说是新的。检查您可以检查您的特定状态()以获得更好的解决方案