【问题标题】:How to add test-package to available sources in Play?如何将测试包添加到 Play 中的可用资源?
【发布时间】:2014-07-29 04:09:34
【问题描述】:

我的 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-class:

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 中,因此我无法在应用文件夹的 GlobalSettings 中访问它。我确实有另一个MockGlobal-class 绑定了我的测试文件夹中的所有其他模拟类以进行测试运行,当然在同一个文件夹中可以访问我的模拟类,所以到目前为止还不错。然后我在测试中使用了这样的模拟全局:

fakeApplication(inMemoryDatabase(), mockGlobalInstance)

我只是尝试将我的测试文件夹中的整个模拟包移动到应用程序文件夹中,只留下测试文件夹中的测试,而不是模拟类。这似乎像你说的那样有效,我只是认为将它们与应用文件夹中的生产类分开会更干净。

PS:我使用 Guice 不仅用于测试,还用于在使用哪些服务时保持灵活性(轻松切换模块)。

【问题讨论】:

  • 这是有意的。普通的应用程序类路径无法访问测试类路径。你想这样做其实很奇怪。如果您在正常的应用运行时需要一个类,只需将其移至应用文件夹即可。
  • 嗯.. 好吧,我刚开始玩 Play,所以如果这很奇怪,也许我只是误解了解剖结构。我是否应该将我的模拟类(例如,我正在模拟一些用 Guice 注入的测试服务)到我的应用程序文件夹?我想这会解决它,我只是认为如果这些类在测试文件夹中会更干净。
  • 也许您可以在 GlobalSettings 中说明您需要的原因。也许你甚至不需要 Guice。多显示一点,我们也许可以弄清楚:-)
  • 好的,我编辑了,希望不会太混乱。无论如何,也许我完全走错了路。 ;)
  • @mavilein 没关系,我放弃了添加额外资源的奇怪计划,只是按照你的建议将运行时需要的类移动到我的应用程序文件夹中。我还更改了仅在一个 GlobalSettings 类中区分生产和测试 Guice 模块的方式,实际上这看起来比以前更清晰。很抱歉造成混乱,并感谢您的提示。如果你愿意,你可以写一个很好的答案和解释,我会接受。 ;)

标签: scala playframework playframework-2.0 sbt


【解决方案1】:

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

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

// 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"
)

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

【讨论】:

  • 很有意义:)
猜你喜欢
  • 1970-01-01
  • 2012-11-23
  • 1970-01-01
  • 2018-09-22
  • 1970-01-01
  • 2019-02-15
  • 2013-04-12
  • 2015-04-15
  • 2020-08-13
相关资源
最近更新 更多