ドキュメント

§アプリケーションのテスト

アプリケーションのテストを作成するには、複雑なプロセスが必要になる場合があります。PlayはJUnitをサポートしており、アプリケーションのテストをできる限り簡単にするためのヘルパーとアプリケーションスタブを提供します。

§概要

テストの場所は「test」フォルダーです。testフォルダーには、テンプレートとして使用できる2つのサンプルテストファイルが作成されています。

sbtコンソールからテストを実行できます。

Playでのテストはsbtに基づいており、詳細についてはテストドキュメントを参照してください。

§JUnitの使用

Playアプリケーションをテストするデフォルトの方法はJUnitを使用することです。

import static org.junit.Assert.*;

import org.junit.Test;

public class SimpleTest {

  @Test
  public void testSum() {
    int a = 1 + 1;
    assertEquals(2, a);
  }

  @Test
  public void testString() {
    String str = "Hello world";
    assertFalse(str.isEmpty());
  }
}

注: testまたはtest-onlyが実行されるたびに、新しいプロセスがフォークされます。新しいプロセスはデフォルトのJVM設定を使用します。カスタム設定はbuild.sbtに追加できます。例:

Test / javaOptions ++= Seq(
  "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9998",
  "-Xms512M",
  "-Xmx1536M",
  "-Xss1M"
)

§アサーションとマッチャー

一部の開発者は、JUnitアサーションよりも流れるようなスタイルでアサーションを記述することを好みます。他のアサーションスタイルのための一般的なライブラリは、便宜上含まれています。

Hamcrestマッチャー

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.assertThat;

import org.junit.Test;

public class HamcrestTest {

  @Test
  public void testString() {
    String str = "good";
    assertThat(str, allOf(equalTo("good"), startsWith("goo")));
  }
}

§モック

モックは、外部依存関係に対する単体テストを分離するために使用されます。たとえば、テスト対象のクラスが外部データアクセスクラスに依存している場合、これをモックして制御されたデータを提供し、外部データリソースの必要性を排除できます。

Mockitoライブラリは、Java用の一般的なモックフレームワークです。テストで使用するには、mockito-coreアーティファクトへの依存関係をbuild.sbtファイルに追加します。例:

libraryDependencies += "org.mockito" % "mockito-core" % "2.10.0" % "test"

mockito-coreの現在のバージョン番号はこちらで確認できます。

Mockitoを使用すると、次のようにクラスまたはインターフェースをモックできます

import static org.mockito.Mockito.*;
// Create and train mock
List<String> mockedList = mock(List.class);
when(mockedList.get(0)).thenReturn("first");

// check value
assertEquals("first", mockedList.get(0));

// verify interaction
verify(mockedList).get(0);

§モデルの単体テスト

次のデータモデルがあると仮定しましょう

public class User {
  private Integer id;
  private String name;

  public User(final Integer id, final String name) {
    this.id = id;
    this.name = name;
  }
}

public class Role {
  private String name;

  public Role(final String name) {
    this.name = name;
  }
}

Ebeanなどの一部のデータアクセスライブラリでは、静的メソッドを使用してデータアクセスロジックをモデルクラスに直接配置できます。これにより、データ依存関係をモックするのが難しくなる場合があります。

テスト容易性のための一般的なアプローチは、モデルをデータベースや可能な限り多くのロジックから分離し、リポジトリインターフェースの背後にデータベースアクセスを抽象化することです。

public interface UserRepository {
  public Set<Role> findUserRoles(User user);
}

public class UserRepositoryEbean implements UserRepository {
  @Override
  public Set<Role> findUserRoles(User user) {
    // Get roles from DB
     ...
  }
}

次に、モデルと対話するためにリポジトリを含むサービスを使用します

public class UserService {
  private final UserRepository userRepository;

  public UserService(final UserRepository userRepository) {
    this.userRepository = userRepository;
  }

  public boolean isAdmin(final User user) {
    final Set<Role> roles = userRepository.findUserRoles(user);
    for (Role role : roles) {
      if (role.name.equals("ADMIN")) return true;
    }
    return false;
  }
}

このようにして、UserService.isAdminメソッドはUserRepository依存関係をモックすることでテストできます

@Test
public void testIsAdmin() {

  // Create and train mock repository
  UserRepository repositoryMock = mock(UserRepository.class);
  Set<Role> roles = new HashSet<Role>();
  roles.add(new Role("ADMIN"));
  when(repositoryMock.findUserRoles(any(User.class))).thenReturn(roles);

  // Test Service
  UserService userService = new UserService(repositoryMock);
  User user = new User(1, "Johnny Utah");
  assertTrue(userService.isAdmin(user));
  verify(repositoryMock).findUserRoles(user);
}

§コントローラーの単体テスト

Playのテストヘルパーを使用してコントローラーをテストし、有用なプロパティを抽出できます。

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static play.mvc.Http.Status.OK;
import static play.test.Helpers.*;

import javaguide.tests.controllers.HomeController;
import org.junit.Test;
import play.mvc.Result;
import play.twirl.api.Content;

public class ControllerTest {

  @Test
  public void testIndex() {
    Result result = new HomeController().index();
    assertEquals(OK, result.status());
    assertEquals("text/html", result.contentType().get());
    assertEquals("utf-8", result.charset().get());
    assertTrue(contentAsString(result).contains("Welcome"));
  }

}

§ビューテンプレートの単体テスト

テンプレートは単なるメソッドであるため、テストから実行して結果を確認できます

@Test
public void renderTemplate() {
    Content html = views.html.index.render("Welcome to Play!");
  assertEquals("text/html", html.contentType());
  assertTrue(contentAsString(html).contains("Welcome to Play!"));
}

§Messagesを使用した単体テスト

単体テストにplay.i18n.MessagesApiインスタンスが必要な場合は、play.test.Helpers.stubMessagesApi()を使用して提供できます

@Test
public void renderMessages() {
  Langs langs = new Langs(new play.api.i18n.DefaultLangs());

  Map<String, String> messagesMap = Collections.singletonMap("foo", "bar");
  Map<String, Map<String, String>> langMap =
      Collections.singletonMap(Lang.defaultLang().code(), messagesMap);
  MessagesApi messagesApi = play.test.Helpers.stubMessagesApi(langMap, langs);

  Messages messages = messagesApi.preferred(langs.availables());
  assertEquals(messages.at("foo"), "bar");
}

次へ:機能テストの作成


このドキュメントにエラーを見つけましたか?このページのソースコードはこちらにあります。ドキュメントガイドラインを読んだら、遠慮なくプルリクエストを送信してください。質問や共有するアドバイスがありますか?コミュニティフォーラムにアクセスして、コミュニティとの会話を始めましょう。