如何在Play中将测试包添加到可用的源?

时间:2014-07-27 11:57:42

标签: scala playframework playframework-2.0 sbt

我的Play Java项目的测试文件夹中有几个模拟类(see anatomy here)。

我还在 app - 和 test - 文件夹中为我的域添加了前缀,但是在Play 2中允许这样做并且工作正常。我的结构现在是这样的:

app
 └ my.domain
   └ conf
   └ controllers
   └ models
   └ views
build.sbt
conf
 └ application.conf
 └ routes             → controller-package for routes definitions adapted to my.domain
test
 └ my.domain
   └ mock             → I want to use sources/classes in here in my app!

我的问题是:我想在我的 app 文件夹中的GlobalSettings中引用 test / my.domain.mock 中的类。但如果我这样做,Play会说cannot find symbol

我设法通过在模块设置中将测试文件夹添加到我的应用程序的源代码来摆脱IntelliJ Idea中的错误,但我不知道如何执行此操作以便Play也识别它。我想我必须改变我的build.sbt文件,我现在就知道如何。我很感激任何建议!

修改

根据要求,这是我目前的GlobalSettings类:

public class Global extends GlobalSettings {

    private final Injector INJECTOR = createInjector();

    @Override
    public void onStart(Application application) {
        super.onStart(application);
    }

    @Override
    public <A> A getControllerInstance(Class<A> controllerClass) throws Exception {
        return INJECTOR.getInstance(controllerClass);
    }

    private static Injector createInjector() {
        return Guice.createInjector(new AbstractModule() {

            @Override
            protected void configure() {
                bind(UrlGenerator.class).to(ProductiveUrlGenerator.class).in(Singleton.class);
                // this is the problem: since I have another MockGlobal (manually inserted as a fake-application parameter) in my test-folder, I don't really need the mocked classes here
                // but for this service in particular, I want to make sure that it's not even used in dev-mode, only productive, but as long as my MockService is in the test-folder I can't access it here
                bind(ImportantService.class).to(Play.isProd() ? ProductiveService.class : MockService.class).in(Singleton.class);
            }
        });
    }
}

就像我在代码中评论的那样,MockService.class位于 test / my.domain.mock 中,因此我无法在app-folder中的GlobalSettings中访问它。我有另一个MockGlobal - 类绑定我的test-folder中的所有其他模拟类用于测试运行,当然在同一个文件夹中可以访问我的模拟类,所以到现在为止那很好。然后我在我的测试中使用了这样的模拟全局:

fakeApplication(inMemoryDatabase(), mockGlobalInstance)

我只是尝试将我的test-folder中的整个mock-package移动到app-folder,只留下测试文件夹中的测试而不是mock-classes。这似乎像你说的那样工作,我只是认为将它们与app-folder中的高效类分开会更清晰。

PS:我不仅使用Guice进行测试,而且还保持灵活使用哪些服务(轻松切换模块)。

1 个答案:

答案 0 :(得分:0)

此行为是这样的。 Play项目(或任何Scala / Java项目)有一个用于应用程序正常运行时的类路径和一个用于测试的类路径。

正常运行时类路径包含启动应用程序所需的所有类。在Play中,此类路径由app文件夹中的类和库依赖项组成。

// example for a library dependency that you can add to your classpath in build.sbt in the project directory
libraryDependencies ++= Seq(
  "com.sksamuel.elastic4s" %% "elastic4s" % "1.0.1.1"
)

测试类路径包含测试应用程序所需的所有类。普通运行时类路径无权访问测试类路径。测试类路径可以访问普通的运行时类路径,因为它需要访问这些类才能测试你的应用程序,对吗?此外,测试类路径包含测试文件夹中的类和使用测试确定范围的库依赖项,例如:

// import the mockito libray that you only use in testing
libraryDependencies ++= Seq(
  "org.mockito" % "mockito-core" % "1.9.5" % "test"
)

<强>结论: 你想要这样做真的很奇怪。如果您需要在正常的应用运行时运行一个类,只需将其移动到app文件夹即可。在正常运行时使用测试类没有多大意义。 如果您想在正常运行时使用它,它不是测试类: - )