玩!框架FakeApplication - 它实际上做了什么?

Joe*_*Joe 6 java database unit-testing playframework

我一直在查看StackOverflow上的一些帖子,看看如何使用MYSQL数据库设置测试.

我只是想测试一些控制器方法,这些方法需要一个带有一些数据的测试数据库才能返回有意义的结果.我想使用一个真正的MYSQL数据库,因为我将在生产中使用它,我已经读过MYSQL和Play提供的InMemory数据库之间存在很多差异.

这个这个博客关于测试Play的帖子中!应用程序,帖子显示了使用数据库参数初始化FakeApplication对象然后调用Helper.start(fakeApp)的示例.

所述文档Helper.start(FakeApplication应用程序)提供了以下描述:

启动一个新的应用程序.

太好了.但实际上是通过调用start来触发哪些进程以及在测试中会给我带来什么?

Map<String, String> settings = new HashMap<String, String>();
settings.put("db.default.url", "jdbc:mysql://localhost/testdb");
settings.put("db.default.user", "root");
settings.put("db.default.password", "");

app = Helpers.fakeApplication(settings);
Helpers.start(app);
Run Code Online (Sandbox Code Playgroud)

我希望上面的代码将Ebean配置为使用我的测试数据库,但是当我尝试执行诸如Ebean.save()之类的方法时,我得到一个错误,表示没有向Ebean注册默认数据库.为了注册我需要填充SERVERCONFIG对象,并创建一个EbeanServerEbeanServerFactory.在那种情况下,将设置映射传递给FakeApplication对象有什么意义吗?再一次,启动FakeApplication实际上做了什么?它怎么用?

提前致谢.

jcr*_*son 4

我知道你一年多前就问过这个问题,但我花了相当长的时间才自己弄清楚这个问题,所以希望这可以在某个时候帮助别人。

当 FakeApplication 运行时,你基本上可以在说“activator run”之后做所有你能做的事情,除了没有网络服务器(netty)运行提供请求之外。不过,您可以测试您的控制器(如此处所示)并调用访问数据库的方法。

实际上,除了这篇文章之外,我还引用了您在解决这个问题时提到的两篇文章,其中讨论了一些必须设置的特殊游戏魔法配置变量,您将在下面的示例中看到这些变量。

我创建了一个抽象的 FakeApplicationTest 类,我在单元/功能测试中扩展了它。我首先使用现有的 application.conf 文件,然后覆盖某些参数以针对不同的数据库进行测试。一旦 FakeApplication 启动,我就会读取所有的演变并创建一个新的数据库来运行我的测试。

public abstract class FakeApplicationTest {

    protected static FakeApplication app;

    /**
     * Create a new FakeApplication using all our custom config vars that test against diff DB's
     *
     * @return
     */
    public static FakeApplication createFakeApp() {
        // grab the main application.conf file that is used to start up the Play application
        Config config = ConfigFactory.parseFile(new File("conf/application.conf"));

        // resolve all variables within this config file with other variables within itself
        config = ConfigFactory.load(config);

        // create a Configuration object out of this and then turn it into a Map to be modified
        Configuration configuration = new Configuration(config);
        Map<String, Object> fakeApplicationConf = Maps.newHashMap(configuration.asMap());

        // do some crazy stuff here because Play wants us to for config voodoo, see:
        // http://www.stupidjavatricks.com/2013/05/changing-play-2-db-configuration-at-runtime-beware-of-dragons/
        Configuration akka = configuration.getConfig("akka.actor.serialization-bindings");
        addValue(fakeApplicationConf, "akka.actor.serialization-bindings", null);
        addValue(fakeApplicationConf, "akka.actor.serialization-bindings.\"[B\"", akka.getString("\"[\"B"));
        addValue(fakeApplicationConf, "akka.actor.serialization-bindings.\"java.io.Serializable\"", akka.getString("\"java.io.Serializable\""));

        // point at a different test database
        addValue(fakeApplicationConf, "db.default.url", "jdbc:mysql://127.0.0.1/testdb");
        addValue(fakeApplicationConf, "db.default.user", "someuser");
        addValue(fakeApplicationConf, "db.default.password", "hunter2");

        // disable evolutions and just create the DB manually
        addValue(fakeApplicationConf, "evolutionplugin", "disabled");

        return Helpers.fakeApplication(fakeApplicationConf);
    }

    @BeforeClass
    public static void setUp() throws Exception {
        app = createFakeApp();

        // fire up the Fake Application!
        Helpers.start(app);

        // after we start up the application, create a database
        createCleanDb();
    }

    @AfterClass
    public static void tearDown() throws Exception {
        Helpers.stop(app);
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

读出这些演变并按顺序应用它们还有很多工作要做,但我现在暂时不谈了。