java - 对 Verticle 部署进行单元测试

标签 java junit rx-java vert.x

我有一个简单的 Verticle,它从属性文件中读取配置并加载到 vertx 配置中。我编写了一个单元测试来测试此 Verticle 的部署,测试失败的可能原因是该位置的属性文件不可用。

当我运行测试时,无论我是否更改属性文件名或路径,单元测试都会通过,并且处理程序表示 Verticle 已成功部署。

我在这里做错了什么吗?下面是我的代码

import io.vertx.config.ConfigRetrieverOptions;
import io.vertx.config.ConfigStoreOptions;
import io.vertx.core.DeploymentOptions;
import io.vertx.core.json.JsonObject;
import io.vertx.rxjava.config.ConfigRetriever;
import io.vertx.rxjava.core.AbstractVerticle;


/**
 * This is the main launcher verticle, the following operations will be executed in start() method of this verticle:
 * 1. Read configurations from application.properties file
 * 2. Deploy all other verticles in the application
 */
public class LauncherVerticle extends AbstractVerticle {


    @Override
    public void start() throws Exception {

        //set up configuration from the properties file
        ConfigStoreOptions fileStore = new ConfigStoreOptions()
                .setType("file")
                .setFormat("properties")
                .setConfig(new JsonObject().put("path", System.getProperty("vertex.config.path"));

        //create config retriever options add properties to filestore
        ConfigRetrieverOptions options = new ConfigRetrieverOptions().addStore(fileStore);
        ConfigRetriever configRetriever = ConfigRetriever.create(vertx, options);

        DeploymentOptions deploymentOptions = new DeploymentOptions();

        //Deploy verticles after the config has been loaded
        //The configurations are loaded into JsonConfig object
        //This JsonConfig object can be accessed in other verticles using the config() method.
        configRetriever.rxGetConfig().subscribe(s -> {

            //pass on the JsonConfig object to other verticles through deployment options
            deploymentOptions.setConfig(s);
            vertx.deployVerticle(AnotherVerticle.class.getName(), deploymentOptions);

        }, e -> {
            log.error("Failed to start application : " + e.getMessage(), e);
            try {
                stop();
            } catch (Exception e1) {
                log.error("Unable to stop vertx, terminate the process manually : "+e1.getMessage(), e1);
            }
        });
    }
}

这是我的单元测试

import io.vertx.ext.unit.TestContext;
import io.vertx.ext.unit.junit.VertxUnitRunner;
import io.vertx.rxjava.core.Vertx;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import rx.Single;


@RunWith(VertxUnitRunner.class)
public class LoadConfigurationTest {


    /**
     * Config should be loaded successfully
     *
     * @param context
     */
    @Test
    public void loadConfigTest(TestContext context) {
        /*
         * Set the system property "vertx.config.path" with value "application.properties"
         * This system property will be used in the Launcher verticle to read the config file
         */
        System.setProperty("vertx.config.path", "/opt/vertx/config/application.properties");

        //create vertx instance
        Vertx vertx = Vertx.vertx();

        Single<String> single = vertx.rxDeployVerticle(LauncherVerticle.class.getName());
        single.subscribe(s -> {
            vertx.rxUndeploy(s);
        }, e -> {
            Assert.fail(e.getMessage());
        });

    }

    /**
     * Test for negative use case - file not available in the specified location
     *
     * @param context
     */
    @Test
    public void loadConfigFailTest(TestContext context) {

         //set path = non existing path
        System.setProperty("vertx.config.path", "/non/existing/path/application.properties");

        //create vertx instance
        Vertx vertx = Vertx.vertx();

        Single single = vertx.rxDeployVerticle(LauncherVerticle.class.getName());

        single.subscribe(s -> {
            //not executing this statement
            Assert.fail("Was expecting error but Verticle deployed successfully");
        }, e -> {
            //not executing this statement either
            System.out.println("pass");
        });
    }
}

最佳答案

您可以在 LauncherVerticle 中尝试以下代码吗?更改仅包括使用 AbstractVerticles startFuture ,其中是一种处理配置加载的巧妙方法,并且在启动过程中一切都相同。

public class LauncherVerticle extends AbstractVerticle {
@Override
public void start(Future<Void> startFuture) throws Exception {
        ConfigStoreOptions fileStore = new ConfigStoreOptions()
                .setType("file")
                .setFormat("properties")
                .setConfig(new JsonObject().put("path", System.getProperty("vertex.config.path")));

        ConfigRetrieverOptions options = new ConfigRetrieverOptions().addStore(fileStore);
        ConfigRetriever configRetriever = ConfigRetriever.create(vertx, options);

        DeploymentOptions deploymentOptions = new DeploymentOptions();
        configRetriever.rxGetConfig().subscribe(s -> {
                    deploymentOptions.setConfig(s);
                    vertx.deployVerticle(AnotherVerticle.class.getName(),
                            deploymentOptions,
                            result -> startFuture.complete()
                    );
                },
                startFuture::fail
        );
    }
}

startFuture 在那里,将帮助您控制 verticle 加载的状态。

还请记住,@Constantine 处理测试的方法是最好的方法,使用 Async 来防止测试在没有实际断言任何内容的情况下通过。

关于java - 对 Verticle 部署进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44527933/

相关文章:

java - 为什么这段Java代码没有并发运行

java - 由于编码问题,Maven 未能通过我的单元测试

java - 动态加载指向由 FXML 构造的多边形的点

java - 如何使用 libGdx 项目弹跳球

java - 使用mockito创建单元测试

android - RxJava 在相同的阻塞 UI 线程上运行并且不显示 AlertDialog

android - RxJava 自定义 ArrayList 也更改引用列表

java - RxJava 中的笛卡尔积

java - 实现特定接口(interface)的类的集合

java - 在 maven 测试运行中执行时,使用 Spring 注释进行测试会导致 ClosedByInterruptException