参数化 Vertx @BeforeClass 应该没有参数

Parameterized Vertx @BeforeClass should have no parameters

我正在尝试使用 JUnit4 实现参数化顶点测试。

使用以下代码时:

@RunWith(Parameterized.class) 
@Parameterized.UseParametersRunnerFactory(
VertxUnitRunnerWithParametersFactory.class)
public class RouteTest {

/**
 * @return the test routes
 */
@Parameters
public static Iterable<String> routes() {
    return Arrays.asList(
    "route1",
    "route2"
    );
}

@Parameter
public String route;

private static Vertx vertx;
private static File dataDir;
private static KafkaCluster kafkaCluster;
private static String URL = "localhost";
private static final int KAFKA_PORT = 9092;
private static final int ZOOKEEPER_PORT = 2181; 


@BeforeClass
public static void setUp(TestContext context) throws Exception {
    vertx = Vertx.vertx();
    setUpKafka(context);
    setUpWebService(context);
}

@AfterClass
public static void tearDownClass(TestContext context){
    vertx.close(context.asyncAssertSuccess(v -> kafkaCluster.shutdown()));
}

public static void setUpWebService(TestContext context) {
    vertx.deployVerticle("com.web.WebServiceVerticle", context.asyncAssertSuccess());
}

public static void setUpKafka(TestContext ctx) {
    Path registryPath = Paths.get(System.getenv("APP_HOME"), "kafka_cluster");
    dataDir = registryPath.toAbsolutePath().toFile();
    kafkaCluster = new KafkaCluster()
            .usingDirectory(dataDir)
            .withPorts(ZOOKEEPER_PORT, KAFKA_PORT)
            .deleteDataPriorToStartup(true)
            .deleteDataUponShutdown(true)
            .addBrokers(1);
    try {
        kafkaCluster.startup();
    } catch (IOException e) {
        ctx.fail(e);
    }
}

private HttpClient getHttpClient() {
    HttpClientOptions options = new HttpClientOptions();
    options.setTryUseCompression(true);
    options.setDefaultHost(URL);
    options.setDefaultPort(PORT);
    return vertx.createHttpClient(options);
}

@Test
public void testUnauthorized(TestContext ctx) {
    Async async = ctx.async();
    getHttpClient().get(route, res -> {
        ctx.assertEquals(401, res.statusCode());
        async.complete();
    }).end();
}

我得到以下输出:

java.lang.Exception: Method setUp should have no parameters

java.lang.Exception: Method tearDownClass should have no parameters

我的预期行为是我在使用 @RunWith(VertxUnitRunner.class) 时遇到的行为。这里 setUptearDown 都自动提供了 TestContext。我不知道有什么方法可以手动创建 TestContext 对象。

使用 @Before 在每次测试时重新部署 Verticle 不是一个选项,因为实际参数集非常大。

我已经考虑添加带有 @Before 的标志以确保 Verticle 仅部署一次,但我想不出一种干净的方法来确保在没有 @AfterClass 注释的情况下正确取消部署

如何正确配置我的测试以提供 @BeforeClass@AfterClass TestContext

我正在使用 vert.x 3.5.1 和 JUnit 4.1.2,并且还得到了您为 @BeforeClass@AfterClass 报告的错误,但不适用于 @Before@After。因此,将代码从 @BeforeClass@AfterClass 移动到 @Before@ After 在技术上是可行的,即使您不喜欢这种方法。你具体关心什么?除了 运行 time/performance 之外还有什么吗?

第二种可能性是使用不带参数的 @BeforeClass@AfterClass 方法,因为您并没有真正充分利用 TestContext 无论如何。 TestContext 在对 vertx.deployVerticle() 的调用中不是必需的,如果 kafkaCluster.startup( ) 失败只是将异常抛回给 @BeforeClass 方法。用这种方法你会失去什么吗?如果不是,您可以将 @BeforeClass@AfterClass 代码更改为:

@BeforeClass
public static void setUp() throws Exception {
    vertx = Vertx.vertx();
    setUpKafka();
    setUpWebService();
}

@AfterClass
public static void tearDownClass() {
    vertx.close();
    // Could also call kafkaCluster.shutdown() if necessary.
}

public static void setUpWebService() {
    vertx.deployVerticle("com.web.WebServiceVerticle");
}

public static void setUpKafka() throws IOException {
    Path registryPath = Paths.get(System.getenv("APP_HOME"), "kafka_cluster");
    dataDir = registryPath.toAbsolutePath().toFile();
    kafkaCluster = new KafkaCluster()
            .usingDirectory(dataDir)
            .withPorts(ZOOKEEPER_PORT, KAFKA_PORT)
            .deleteDataPriorToStartup(true)
            .deleteDataUponShutdown(true)
            .addBrokers(1);
    kafkaCluster.startup();
}

第三种可能性是采用完全不同的测试方法,using a TestSuite which allows you to specify a callback to be executed before and after the tests, with TestContext being available. You don't need JUnit at all. See the the specs for the before() and after() methods. There are also beforeEach() and afterEach() methods. Here's sample code 来自 Vertx 的网站:

TestSuite suite = TestSuite.create("the_test_suite");
suite.before(context -> {
  // Test suite setup
}).test("my_test_case_1", context -> {
  // Test 1
}).test("my_test_case_2", context -> {
  // Test 2
}).test("my_test_case_3", context -> {
  // Test 3
}).after(context -> {
  // Test suite cleanup
});