春豆にモッキートモックを注入する

MockitoモックをSpring Beanに注入する

1. 概要

この記事では、依存関係注入を使用して、Mockitoモックを単体テスト用のSpring Beanに挿入する方法を示します。

コンポーネントが外部システムへのアクセスに依存することが多い実世界のアプリケーションでは、適切なテスト分離を提供することが重要です。これにより、各テストにクラス階層全体を関与させることなく、特定のユニットの機能のテストに集中できます。

モックの注入は、このような分離を導入するためのクリーンな方法です。

2. Mavenの依存関係

単体テストとモックオブジェクトには、次のMaven依存関係が必要です。


    org.springframework.boot
    spring-boot-starter
    1.3.1.RELEASE


    org.springframework.boot
    spring-boot-starter-test
    1.3.1.RELEASE
    test


    org.mockito
    mockito-core
    2.21.0

この例ではSpring Bootを使用することにしましたが、従来のSpringでも問題なく動作します。

3. テストを書く

3.1. ビジネスロジック

最初に、テストするビジネスロジックを記述します。

@Service
public class NameService {
    public String getUserName(String id) {
        return "Real user name";
    }
}

NameServiceクラスは次の場所に挿入されます。

@Service
public class UserService {

    private NameService nameService;

    @Autowired
    public UserService(NameService nameService) {
        this.nameService = nameService;
    }

    public String getUserName(String id) {
        return nameService.getUserName(id);
    }
}

このチュートリアルでは、指定されたクラスは、指定されたIDに関係なく単一の名前を返します。 これは、複雑なロジックをテストすることに気を取られないようにするためです。

Beanをスキャンしてアプリケーションを初期化するには、標準のSpring Bootメインクラスも必要です。

@SpringBootApplication
public class MocksApplication {
    public static void main(String[] args) {
        SpringApplication.run(MocksApplication.class, args);
    }
}

3.2. テスト

それでは、テストロジックに移りましょう。 まず、テスト用のアプリケーションコンテキストを構成する必要があります。

@Profile("test")
@Configuration
public class NameServiceTestConfiguration {
    @Bean
    @Primary
    public NameService nameService() {
        return Mockito.mock(NameService.class);
    }
}

@Profileアノテーションは、「テスト」プロファイルがアクティブな場合にのみこの構成を適用するようにSpringに指示します。 @Primaryアノテーションは、自動配線に実際のインスタンスではなく、このインスタンスが使用されるようにするためにあります。 メソッド自体は、NameServiceクラスのMockitoモックを作成して返します。

これでユニットテストを書くことができます:

@ActiveProfiles("test")
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MocksApplication.class)
public class UserServiceUnitTest {

    @Autowired
    private UserService userService;

    @Autowired
    private NameService nameService;

    @Test
    public void whenUserIdIsProvided_thenRetrievedNameIsCorrect() {
        Mockito.when(nameService.getUserName("SomeId")).thenReturn("Mock user name");
        String testName = userService.getUserName("SomeId");
        Assert.assertEquals("Mock user name", testName);
    }
}

@ActiveProfilesアノテーションを使用して、「テスト」プロファイルを有効にし、前に作成したモック構成をアクティブにします。 このため、SpringはUserServiceクラスの実際のインスタンスを自動配線しますが、NameServiceクラスのモックを自動配線します。 テスト自体は、かなり典型的なJUnit + Mockitoテストです。 モックの目的の動作を設定し、テストするメソッドを呼び出して、期待する値を返すことをアサートします。

また、このようなテストで環境プロファイルを使用しないようにすることもできます(推奨されません)。 これを行うには、@Profile and @ActiveProfilesアノテーションを削除し、@ContextConfiguration(classes = NameServiceTestConfiguration.class)アノテーションをUserServiceTestクラスに追加します。

4. 結論

チュートリアルでは、MockitoモックをSpring Beanに注入する方法を示しました。 実装はexample GitHub projectにあります。