§アプリケーションのテスト
アプリケーションのテストを作成するには、複雑なプロセスが必要になる場合があります。PlayはJUnitをサポートしており、アプリケーションのテストをできる限り簡単にするためのヘルパーとアプリケーションスタブを提供します。
§概要
テストの場所は「test」フォルダーです。testフォルダーには、テンプレートとして使用できる2つのサンプルテストファイルが作成されています。
sbtコンソールからテストを実行できます。
- すべてのテストを実行するには、
test
を実行します。 - 1つのテストクラスのみを実行するには、
testOnly
の後にクラス名(例:testOnly my.namespace.MyTest
)を指定して実行します。 - 失敗したテストのみを実行するには、
testQuick
を実行します。 - テストを継続的に実行するには、コマンドの前にチルダを付けて実行します。例:
~testQuick
。 - コンソールで
FakeApplication
などのテストヘルパーにアクセスするには、Test/console
を実行します。
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");
}
次へ:機能テストの作成
このドキュメントにエラーを見つけましたか?このページのソースコードはこちらにあります。ドキュメントガイドラインを読んだら、遠慮なくプルリクエストを送信してください。質問や共有するアドバイスがありますか?コミュニティフォーラムにアクセスして、コミュニティとの会話を始めましょう。