Dropwizard集成测试与模拟DB

时间:2015-03-05 09:20:44

标签: testing junit mockito dropwizard

第一:是的,我读了https://dropwizard.github.io/dropwizard/manual/testing.html

我想做一些集成测试,并且为什么我必须启动整个应用程序。现在的问题是,我有一些接口到“外部世界”,如DB或一个内部Rest-Client,他们使用一个远程应用程序。我想用mockito嘲笑他们。通常没问题。

现在我的问题:如何使用模拟数据库和模拟客户端启动整个应用程序?

目前的问题是,我通过getDBClient()从我的配置类中获得了这个数据库连接和客户端...而且我不愿意在我的配置中构建一些测试代码,因为它的生产代码。因此,如果我通过DropwizardAppRule启动整个应用程序,该应用程序会尝试连接到数据库,但在测试环境中,没有可用的数据库。

有没有简单的说法:启动我的应用程序但是如果你调用数据库或客户端,那么使用这个XY模拟?

我还尝试了什么: 一个新类“ExtendedService extends Service extends Application”和一个“ExtServiceConfiguration扩展ServiceConfiguration”,但没有任何成功。但是如果我重写了返回模拟的config类中的某些方法,我会遇到麻烦。它并不适合所有人。

目前我阅读了mockito spy的文档,也许这可以提供帮助,但我不确定如何在DW集成测试中使用它。我现在尝试模拟我的两个配置类方法来返回数据库和客户端模拟。也许有人可以帮助我,如何在下一个示例代码中模拟TestConfiguration:

@ClassRule
public static final DropwizardAppRule<TestConfiguration> RULE =
        new DropwizardAppRule<TestConfiguration>(MyApp.class, resourceFilePath("my-app-config.yaml"));

编辑:     @ClassRule     public static final DropwizardAppRule RULE = new DropwizardAppRule(.....)

在@BeforeClass中,我执行以下操作:

ServiceConfiguration oldConfig = RULE.getConfiguration();
ServiceConfiguration spy = Mockito.spy(oldConfig);
//Then DB mocking
IDatabaseLayer dBMock = mock(IDatabaseLayer.class);
Mockito.when(dBMock.isConnected()).thenReturn(true);
... // other mocking functions for DB
//this is important, it say, that the mocked config class should use the mocked DB
Mockito.doReturn(dBMock).when(spy).getDataBaseLayer(); // my configuration class has this method, so mocking config class with last created dbMock
// do other mockings if needed

这就是我开始整个申请所做的一切。

3 个答案:

答案 0 :(得分:4)

如果你想模拟特定的东西,但仍然保持整个dropwizard的流程,那么你需要管理自己的Application实例,并且可以将你的依赖项注入到你的Application类中。因为DropwizardAppRule并没有为您提供这种灵活性。

示例:您希望能够覆盖应用程序类的依赖项。

public class MyApplication extends Application {

  private FooManager fooManager;

  // Need to leave an empty constructor for other uses
  public MyApplication(){
  }

  public MyApplication(FooManager fooManager){
    this.fooManager = fooManager;
  }

  @Override
  public void run(Configuration configuration, Environment environment) throws Exception {
    if(fooManager == null){
      fooManager = new FooManagerImpl();
    }
    // stuff
  }
}

然后在测试中,您创建自己的实例(或者您可以通过复制和修改DropwizardAppRule源代码来创建规则类。编辑:看起来您可以继承{{1 }}并覆盖DropwizardTestSupport。)。

public Application<C> newApplication()

答案 1 :(得分:3)

如果您真的想要运行集成测试,我建议使用内存或临时数据库,如h2sqlite,如果可以,可以通过创建具有相关设置的新yml文件;并使用模拟的http服务,例如Wiremock

否则坚持ResourceTestRule s,因为th3morg建议。

答案 2 :(得分:2)

我认为您应该使用io.dropwizard.testing.junit.ResourceTestRule,它用于测试Jersey资源(即调用REST API端点)。 DropwizardAppRule将启动整个应用程序并在测试结束时停止它。该类似乎是用于端到端测试,在这种测试中你不会做任何嘲弄。