Micronautテストに依存関係をオーバーライド

安っぽく:

私はそれに注入Beanを持つMicronautクラスをテストしています。私のテストでは、私は提供し@MockBean、それをオーバーライドするクラスを。しかし、Micronautはまだ本当の依存性を注入しそうです。

@MicronautTest
public class ClassUnderTestTest {

    @Inject ClassUnderTest classUnderTest;

    @Test
    public void test() {

    }

    @MockBean
    Dependency dependency() {
        return mock(Dependency.class);
    }

}

:私はGithubの最小REPROアップロードhttps://github.com/crummy/micronaut-test-dependenciesを本当の依存性は、例外をスローし、テストも行います。私は、これが原因で、私の起こることを期待しなかったであろう@MockBean

私がする注釈を変更した場合@MockBean(Dependency.class)、私はこのエラーを取得します:Message: No bean of type [di.failure.example.Dependency] existsこれは私にはさらに混乱ようだ-今、それは私の本当のか、私のモックの依存関係が解決されませんか?

サイモンStepniak:

モックBeanを注入@MockBean中に、あなたの依存関係があれば、注釈の作品ClassUnderTestインターフェースによって表されます。発言はしてみましょうDependencyのようなシンプルなインターフェイスです。

package di.failure.example;

public interface Dependency {
    void run();
}

あなたのアプリと呼ばれるこのインタフェースの実装を提供することができますDependencyImpl

package di.failure.example;

import javax.inject.Singleton;

@Singleton
public class DependencyImpl implements Dependency {
    @Override
    public void run() {
        throw new RuntimeException("I don't want this to load!");
    }
}

さて、テスト目的のために、あなたは置き換え、そのモックを定義することができますDependencyImpl

package di.failure.example;

import io.micronaut.test.annotation.MicronautTest;
import io.micronaut.test.annotation.MockBean;
import org.junit.jupiter.api.Test;

import javax.inject.Inject;

import static org.mockito.Mockito.mock;

@MicronautTest
public class ClassUnderTestTest {

    @Inject
    ClassUnderTest classUnderTest;

    @Test
    public void test() {
        classUnderTest.run();
    }

    @MockBean(DependencyImpl.class)
    public Dependency dependency() {
        return mock(Dependency.class);
    }

}

このテストを実行してから返されたモックdependency()メソッドの代わりに使用されていますDependencyImpl

使用して@Replaces注釈を

セルジオは、コメント欄で述べたあなたが使用してクラスベースのBeanの依存関係を置き換えることができ@Replaces、注釈を。次の例を考えてみます。

package di.failure.example;

import io.micronaut.context.annotation.Replaces;
import io.micronaut.test.annotation.MicronautTest;
import org.junit.jupiter.api.Test;

import javax.inject.Inject;
import javax.inject.Singleton;

@MicronautTest
public class ClassUnderTestTest {

    @Inject
    ClassUnderTest classUnderTest;

    @Test
    public void test() {
        classUnderTest.run();
    }

    @Replaces(Dependency.class)
    @Singleton
    public static class MockDependency extends Dependency {

        public MockDependency() {
            System.out.println("MockDependency.<init>");
        }

        @Override
        void run() {
            System.out.println("Does not throw any exception...");
        }
    }
}

この例では、クラスを定義しているMockDependencyと我々は交換するMicronautのDIメカニズム指示Dependencyで豆をMockDependencyしかし、私たちが覚えておく必要がある1つ重要なことがある-私たちはので、MockDependency拡張Dependencyクラスを、親構築物が呼び出されます。ので、あなたが疑問に示した例では、このケースでは動作しませんDependency.<init>投げRuntimeException、テストが失敗しました。この変形例では私はこの1つのように使用するクラスを持っています:

package di.failure.example;

import javax.inject.Singleton;

@Singleton
public class Dependency {

    public Dependency() {
        System.out.println("Dependency.<init>");
    }

    void run() {
        throw new RuntimeException("I don't want this to load!");
    }
}

私は、テストを実行すると、それは通過して、私は次のコンソール出力を参照してください。

Dependency.<init>
MockDependency.<init>
Does not throw any exception...

比較主な違いは、@MockBeanの場合であることである@Replacesあなたの具象クラスのオブジェクトを使用しています。回避策として(私たちは本当にMockitoモックオブジェクトが必要な場合)、内部でモックを作成し、このオブジェクトへの呼び出しを委任し、このようなものです:

@Replaces(Dependency.class)
@Singleton
public class MockDependency extends Dependency {

    private final Dependency delegate;

    public MockDependency() {
        this.delegate = mock(Dependency.class);
    }

    @Override
    void run() {
        delegate.run();
    }
}

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=177661&siteId=1