1前書き



ReflectionTestUtils


は、Spring Test Contextフレームワークの一部です。これは、ユニットで使用されるリフレクションベースのユーティリティメソッド、および非公開フィールドの設定、非公開メソッドの呼び出し、および依存関係の注入を行うための統合テストシナリオのコレクションです。

このチュートリアルでは、いくつかの例を通して、単体テストで

ReflectionTestUtils

を使用する方法について説明します。


2 Mavenの依存関係

例に必要なすべての必要な依存関係の最新バージョンを

pom.xml

に追加することから始めましょう。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.2.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.1.2.RELEASE</version>
    <scope>test</scope>
</dependency>

最新の

__https://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22org.springframework%22%20AND%20a%3A%22spring-context%22、https://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22org.springframework%22%20AND%20a%3A%22spring-test%22[spring-test]

__dependenciesはMavenからダウンロードできます。中央リポジトリ

3.

ReflectionTestUtils

を使用して非公開フィールドの値を設定する

単体テストで、public setterメソッドを使用せずに、privateフィールドを持つクラスのインスタンスを使用する必要があるとします。

それを作成することから始めましょう:

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

   //standard getters/setters
}

テスト用の値を割り当てるためにプライベートフィールド

id

にアクセスすることは通常できません。パブリックセッターメソッドがないためです。

その後、

ReflectionTestUtils.setField

メソッドを使用して、プライベートメンバー

id

に値を割り当てることができます。

@Test
public void whenNonPublicField__thenReflectionTestUtilsSetField() {
    Employee employee = new Employee();
    ReflectionTestUtils.setField(employee, "id", 1);

    assertTrue(employee.getId().equals(1));
}

4.

ReflectionTestUtils

を使用して非公開メソッドを呼び出す


Employee

クラスにプライベートメソッド

employeeToString

があるとします。

private String employeeToString(){
    return "id: " + getId() + "; name: " + getName();
}


Employee

クラスの外部からアクセスすることはできませんが、以下のように

employeeToString

メソッドのユニットテストを書くことができます。

@Test
public void whenNonPublicMethod__thenReflectionTestUtilsInvokeMethod() {
    Employee employee = new Employee();
    ReflectionTestUtils.setField(employee, "id", 1);
    employee.setName("Smith, John");

    assertTrue(ReflectionTestUtils.invokeMethod(employee, "employeeToString")
      .equals("id: 1; name: Smith, John"));
}

5.依存関係を注入するための

ReflectionTestUtils

の使用


@ Autowired

アノテーション付きのプライベートフィールドを持つ次のSpringコンポーネントのユニットテストを書きたいとしましょう。

@Component
public class EmployeeService {

    @Autowired
    private HRService hrService;

    public String findEmployeeStatus(Integer employeeId) {
        return "Employee " + employeeId + " status: " + hrService.getEmployeeStatus(employeeId);
    }
}

以下のように

HRService

コンポーネントを実装できます。

@Component
public class HRService {

    public String getEmployeeStatus(Integer employeeId) {
        return "Inactive";
    }
}

さらに、https://www.baeldung.com/mockito-annotations[Mockito]を使用して、

HRService

クラスのモック実装を作成しましょう。

このモックを

EmployeeService

インスタンスに挿入し、単体テストで使用します。

HRService hrService = mock(HRService.class);
when(hrService.getEmployeeStatus(employee.getId())).thenReturn("Active");


hrService

はパブリックセッターを持たないプライベートフィールドなので、

ReflectionTestUtils.setField

メソッドを使用して、上記で作成したモックをこのプライベートフィールドに挿入します。

EmployeeService employeeService = new EmployeeService();
ReflectionTestUtils.setField(employeeService, "hrService", hrService);

最後に、私たちのユニットテストはこれに似たものになるでしょう。

@Test
public void whenInjectingMockOfDependency__thenReflectionTestUtilsSetField() {
    Employee employee = new Employee();
    ReflectionTestUtils.setField(employee, "id", 1);
    employee.setName("Smith, John");

    HRService hrService = mock(HRService.class);
    when(hrService.getEmployeeStatus(employee.getId())).thenReturn("Active");
    EmployeeService employeeService = new EmployeeService();

   //Inject mock into the private field
    ReflectionTestUtils.setField(employeeService, "hrService", hrService);

    assertEquals(
      "Employee " + employee.getId() + " status: Active",
      employeeService.findEmployeeStatus(employee.getId()));
}

6.まとめ

このチュートリアルでは、いくつかの例を通して、単体テストで

ReflectionTestUtils

を使用する方法を示しました。

いつものように、コードサンプルはhttps://github.com/eugenp/tutorials/tree/master/testing-modules/spring-testing[Githubに追加]を見つけることができます。