Play Framework 2.5.x 測試環境搭建
目錄
準備工作
Play 2.5.x Project Based on SBT
- 自帶 Junit 4.12
- 自帶 Guice 4.0
Mockito (2.2.11)
目標
搭建基於 Dependency Inject (使用 Guice) 的 PlayJava 工程的測試環境
GO
build.sbt
添加以下依賴:
libraryDependencies += "org.mockito" % "mockito-core" % "2.2.11" % "test"
設置 JavaOption:
javaOptions in Test ++= Seq(
"-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=9998",
"-Xms512M",
"-Xmx1536M",
"-Xss1M",
"-XX:MaxPermSize=384M",
"-Dconfig.resource=application.test.conf",
"-Dlogger.resource=logback-test.xml"
)
conf/
在 build.sbt 中定義的 application.test.conf 和 logback-test.xml 要放置在工程根目錄下的 conf/ 中。
如果不想 testcase 在 run 的過程中產生煩人的日誌,在 logback-test.xml 中配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<!-- SHUT THE LOG UP! -->
<configuration />
在 application.test.conf 配置文件中添加如下一行
application.global=TestGlobal
將 test 的 Global 跟 production 的 Global 區分開來。
TestGlobal
TestGlobal 類如下:
import play.Application;
import play.GlobalSettings;
/**
* Created by STEPHEN on 06/12/17.
*/
public class TestGlobal extends GlobalSettings {
private static final String TAG = TestGlobal.class.getSimpleName();
@Override
public void onStart(Application app) {
}
@Override
public void onStop(Application app) {
}
}
將 TestGlobal.java 文件放置在 工程根目錄的 test/ 下。
應用
開發中的邏輯幾乎都在 Service 層中,那麼最常見的就是對 Service 進行 Unit Test。假設有兩個類 – Service 和 Dao。 簡單定義如下:
public class Service {
@Inject
private Dao dao;
public Document getQualifiedUser(String uid) {
Document user = dao.getUserById(uid);
/* 針對這個 user 會有很多的處理,比如 validation 等等 */
/* ... */
/* 最終返回 user */
return user;
}
}
public class DaoImpl implement Dao {
private static SomeDB sdb = SomeDBFactory.get();
@Override
public Document getUserById(String uid) {
return sdb.find(id=uid).one();
}
}
針對這種常見的模型,可以進行如下的操作:
test/
在 test/ 下新建 servicetest/unittest/ServiceTest.java
內容如下:
abstract class ServiceTest {
Dao dao;
Injector injector;
@Before
public void setUp() throws Exception {
dao = Mockito.mock(DaoImpl.class);
injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
bind(Dao.class).toInstance(dao);
}
});
}
@After
public void tearDown() throws Exception {
injector = null;
dao = null;
}}
再建立真正的測試類:
public class SpecificServiceTest extends ServiceTest {
@Test
public void testGetUserById() {
/* MOCK BEGIN */
/* mock db queries one user */
when(dao.getUserById(anyString()))
.thenReturn(new Document("name", "stephen").append("age", 25));
/* MOCK END */
/* CALL BEGIN */
Service service = injector.getInstance(Service.class);
Document user = service.getQualifiedUser("13");
/* CALL END */
/* ASSERT BEGIN */
assertEquals("stephen", user.getString("name"));
assertEquals(25, user.getInt("age"));
/* ASSERT END */
}
}
在工程目錄下,輸入:
activator test
Ok!