如果 中的依赖项由接口表示,则注入带有注释的模拟 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!");
}
}
现在,出于测试目的,您可以定义一个 mock 来替换 :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);
}
}
将执行此测试,并使用 方法返回的 mock 代替 。dependency()
DependencyImpl
使用批注@Replaces
正如Sergio在注释部分中提到的,您可以使用@Replaces注释替换基于类的
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...");
}
}
}
在这个例子中,我们定义了一个类,我们指示Micronaut的DI机制用.但是,我们需要记住一件重要的事情 - 因为我们的扩展类,父构造被调用。在这种情况下,您在问题中显示的示例将不起作用,因为抛出和测试失败。在这个修改后的示例中,我使用了如下类:MockDependency
Dependency
MockDependency
MockDependency
Dependency
Dependency.<init>
RuntimeException
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...
与 相比,主要区别在于,如果您使用的是具体的类对象。作为解决方法(如果我们真的需要一个Mockito模拟对象)是在内部创建一个模拟并将调用委托给这个对象,如下所示:@MockBean
@Replaces
@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();
}
}