Java 重写Micronaut测试中的依赖项

Java 重写Micronaut测试中的依赖项,java,dependency-injection,micronaut,Java,Dependency Injection,Micronaut,我正在测试一个Micronaut类,该类中注入了一个bean。在我的测试中,我提供了一个@MockBean类来覆盖它。然而,Micronaut似乎仍然注入了真正的依赖性 @MicronautTest public class ClassUnderTestTest { @Inject ClassUnderTest classUnderTest; @Test public void test() { } @MockBean Dependency

我正在测试一个Micronaut类,该类中注入了一个bean。在我的测试中,我提供了一个
@MockBean
类来覆盖它。然而,Micronaut似乎仍然注入了真正的依赖性

@MicronautTest
public class ClassUnderTestTest {

    @Inject ClassUnderTest classUnderTest;

    @Test
    public void test() {

    }

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

}
我向Github上传了一个最低限度的复制:。真正的依赖项抛出异常,测试也抛出异常。由于我的
@MockBean
,我不希望发生这种情况


如果我将注释更改为
@MockBean(Dependency.class)
,那么我会得到以下错误:
消息:不存在[di.failure.example.Dependency]类型的bean
。这似乎让我更加困惑-现在它无法解决我的真实或模拟依赖关系?

如果您在
ClassUnderTest
中的依赖关系由接口表示,则使用
@MockBean
注释注入模拟bean是可行的。假设
依赖关系
是一个简单的界面,如:

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!");
    }
}
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);
    }

}
现在,出于测试目的,您可以定义一个替换
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!");
    }
}
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

使用
@替换
注释 如注释部分所述,您可以使用注释替换基于类的bean依赖关系。考虑下面的例子:

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...");
        }
    }
}
当我运行测试时,它通过了测试,我看到以下控制台输出:

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

好吧,这是一个遗憾(除非我有实际的需要,否则我更喜欢避免接口。)但我想这是一个。如果你需要替换一个类,你可以在测试类路径中创建一个bean,并使用@ReplacesThanks@SergiodelAmo来获得有价值的输入!我已经用
@替换了
注释用例更新了答案。我想要覆盖的是属性值,而不是整个bean?典型的例子是内存数据库。“我想要覆盖的是一个属性值,而不是整个bean吗?”-您可以使用特定于环境的配置文件,如
src/main/resources/application test.yml
。标有
@MicronautTest
的测试也可以提供自己的配置值。