使用junit

时间:2018-06-24 12:02:26

标签: testing junit dropwizard

我有一个测试类,其中包含多个测试。目前,我有这个来启动服务器,擦除数据库,等等:

@ClassRule
public static final DropwizardAppRule<ServiceConfig> RULE =
        new DropwizardAppRule<ServiceConfig>(ServiceApp.class, ResourceHelpers.resourceFilePath("config.yml"));

我所有的测试都单独使用。但是当我一起运行它们时,由于其他测试会修改数据,因此它们会失败。我尝试执行以下操作,但在调用RULE.getPort()时却得到了空指针:

@ClassRule
public static DropwizardAppRule<ServiceConfig> RULE;

@Before
public void beforeClass() {
     RULE = new DropwizardAppRule<ServiceConfig>(ServiceApp.class, ResourceHelpers.resourceFilePath("config.yml"));
}

我希望它能起作用,但是似乎无法正确设置RULE的值。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

嗨,
我不知道如何从DropwizardAppRule内部处理db,所以我可能无法真正回答您的问题...我自己在尝试DropwizardAppRule的另一个问题是在测试之间没有正确设置和拆除。 (因此,如果您以这种方式取得了进展,我希望您提供见解)。


无论如何,我认为您需要在DropwizardAppRule之外处理您的数据库并将其放入规则中。我们依靠自定义和外部TestsRules解决了数据库清除问题:

public class CockpitApplicationRule implements TestRule {

public static class App extends CockpitApplication<CockpitConfiguration> {
    // only needed because of generics
}

public final DropwizardAppRule<CockpitConfiguration> dw;

public final EmbeddedDatabaseRule db;

public CockpitApplicationRule(String config, ConfigOverride... configOverrides) {
    this.db = EmbeddedDatabaseRule.builder()
            .initializedByPlugin(LiquibaseInitializer.builder().withChangelogResource("migrations.xml").build())
            .build();
    this.dw = new DropwizardAppRule<>(App.class, ResourceHelpers.resourceFilePath(config),
            ConfigOverride.config("database.url", () -> this.db.getConnectionJdbcUrl()));
}

@Override
@Nullable
public Statement apply(@Nullable Statement base, @Nullable Description description) {
    assert base != null;
    assert description != null;

    return RulesHelper.chain(base, description, dw, RulesHelper.dropDbAfter(db), db);
}

public DSLContext db() {
    return DSL.using(db.getConnectionJdbcUrl());
}
}

基本上,我们重写TestRule apply(...)以链接自定义语句。 There's our RulesHelper if you want to take a look。这样,规则就可以干净地处理数据库,我们可以使用@Before设置方法将测试数据库填充到测试类中。

org.zapodot.junit.db.EmbeddedDatabaseRule是一个外部依赖关系,它使我们可以轻松地为测试实例化数据库。

RulesHelper.dropDbAfter进行实际清洁:

public static TestRule dropDbAfter(EmbeddedDatabaseRule db) {
    return after(() -> DSL.using(db.getConnectionJdbcUrl()).execute("DROP ALL OBJECTS"));
}

尽管没有完全使用TestRules,您应该能够从@Before@After方法中设置和清除数据库,但是我不确定最后是否真的更容易。

希望这对您有帮助!