我有一个测试类,其中包含多个测试。目前,我有这个来启动服务器,擦除数据库,等等:
@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的值。有什么想法吗?
答案 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
方法中设置和清除数据库,但是我不确定最后是否真的更容易。
希望这对您有帮助!