單元測試 - Java Play 2.42.5

助手和假應用程式

Class Helpers 用於單元測試。它模仿 Play 應用程式,偽造 HTTP 請求和響應,會話,cookie - 所有測試可能需要的東西。測試中的控制器應該在 Play 應用程式的上下文中執行。的助手方法 fakeApplication 提供了一種用於執行測試的應用程式。為了使用 HelpersfakeApplication ,測試類應該派生自 WithApplication

應使用以下 Helpers API:

Helpers.running(Application application, final Runnable block);
Helpers.fakeApplication();

使用助手進行測試如下所示:

public class TestController extends WithApplication {
 @Test  
 public void testSomething() {  
     Helpers.running(Helpers.fakeApplication(), () -> {  
         // put test stuff  
         // put asserts  
     });
 }  
}  

為 Helpers 方法新增 import 語句使程式碼更緊湊:

 import static play.test.Helpers.fakeApplication;
 import static play.test.Helpers.running;
 ...
 @Test  
 public void testSomething() {  
      running(fakeApplication(), () -> {  
           // put test stuff  
           // put asserts  
       });
 }

}

測試控制器

讓我們呼叫一個控制器方法,該方法作為路由方法繫結到路由中的特定 URL。呼叫路由方法稱為控制器操作,並具有 Java 型別呼叫。Play 為每個動作構建所謂的反向路徑。呼叫反向路由會建立適當的 Call 物件。該反向路由機制用於測試控制器。 **** **** **** ** **

要從 test 呼叫控制器操作,應使用以下 Helpers API:

Result result = Helpers.route(Helpers.fakeRequest(Call action));

控制器測試示例

  1. 路線
GET /conference/:confId    controllers.ConferenceController.getConfId(confId: String)  
POST /conference/:confId/participant controllers.ConferenceController.addParticipant(confId:String) 
  1. 生成的反向路線:

    controllers.routes.ConferenceController.getConfId(conferenceId) 
    controllers.routes.ConferenceController.addParticipant(conferenceId)
    
  2. 方法 getConfId 繫結到 GET ,並且不在請求中接收正文。可以呼叫它來進行測試:

    Result result = Helpers.route(Helpers.fakeRequest(controllers.routes.ConferenceController.getConfId(conferenceId)));
    
  3. 該方法 addParticipant 勢必 POST 。它希望在請求中收到一個正文。它在測試中的呼叫應該像這樣:

    ParticipantDetails inputData = DataSimulator.createParticipantDetails();
    Call action = controllers.routes.ConferenceController.addParticipant(conferenceId);
    Result result = route(Helpers.fakeRequest(action).bodyJson(Json.toJson(inputData));
    

嘲笑 PowerMock

要啟用模擬,測試類應註釋如下:

@RunWith(PowerMockRunner.class)
@PowerMockIgnore({"javax.management.*", "javax.crypto.*"})
public class TestController extends WithApplication {
....

模擬控制器動作

使用 RequestBuilder 模擬控制器呼叫 :

RequestBuilder fakeRequest = Helpers.fakeRequest(action); 

對於上面的 addParticipant,操作被模擬為:

RequestBuilder mockActionRequest = Helpers.fakeRequest(controllers.routes.ConferenceController.addParticipant(conferenceId)); 

要呼叫控制器方法:

Result result = Helpers.route(mockActionRequest);

整個測試:

@Test
public void testLoginOK() {
 running(fakeApplication(), () -> {
      ///*whatever mocking*/Mockito.when(...).thenReturn(...);
      RequestBuilder mockActionRequest = Helpers.fakeRequest(
           controllers.routes.LoginController.loginAdmin());
      Result result = route(mockActionRequest);
      assertEquals(OK, result.status());
 });
}

使用 JSON 正文模擬動作

我們假設輸入是 T 型別的物件。動作請求模擬可以以幾種方式完成。

選項 1:

public static <T> RequestBuilder fakeRequestWithJson(T input, String method, String url) {  
  JsonNode jsonNode = Json.toJson(input);  
  RequestBuilder fakeRequest = Helpers.fakeRequest(method, url).bodyJson(jsonNode);  
  System.out.println("Created fakeRequest="+fakeRequest +", body="+fakeRequest.body().asJson());  
  return fakeRequest;  
}  

選項 2:

public static <T> RequestBuilder fakeActionRequestWithJson(Call action, T input) {  
  JsonNode jsonNode = Json.toJson(input);  
  RequestBuilder fakeRequest = Helpers.fakeRequest(action).bodyJson(jsonNode);  
  System.out.println("Created fakeRequest="+fakeRequest +", body="+fakeRequest.body().asJson());  
  return fakeRequest;  
} 

使用基本身份驗證標頭模擬操作

動作請求嘲笑:

public static final String BASIC_AUTH_VALUE = "dummy@com.com:12345";
public static RequestBuilder fakeActionRequestWithBaseAuthHeader(Call action) {
  String encoded = Base64.getEncoder().encodeToString(BASIC_AUTH_VALUE.getBytes());
  RequestBuilder fakeRequest = Helpers.fakeRequest(action).header(Http.HeaderNames.AUTHORIZATION,
                                             "Basic " + encoded);
  System.out.println("Created fakeRequest="+fakeRequest.toString() );
  return fakeRequest;
}

用會話嘲笑動作

動作請求嘲笑:

public static final String FAKE_SESSION_ID = "12345";
public static RequestBuilder fakeActionRequestWithSession(Call action) {
  RequestBuilder fakeRequest = RequestBuilder fakeRequest = Helpers.fakeRequest(action).session("sessionId", FAKE_SESSION_ID);
  System.out.println("Created fakeRequest="+fakeRequest.toString() );
  return fakeRequest;
}

Play Session 類只是 HashMap <String,String> 的擴充套件。它可能會被簡單的程式碼嘲笑:

public static Http.Session fakeSession() {  
  return new Http.Session(new HashMap<String, String>());  
}