Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用@InjectMocks用模拟实现替换@Autowired字段_Java_Unit Testing_Junit_Spring Boot_Mockito - Fatal编程技术网

Java 使用@InjectMocks用模拟实现替换@Autowired字段

Java 使用@InjectMocks用模拟实现替换@Autowired字段,java,unit-testing,junit,spring-boot,mockito,Java,Unit Testing,Junit,Spring Boot,Mockito,我想用我专门为测试而创建的类的模拟实现替换spring boot应用程序中的一个自动连接的服务类 我之所以选择创建这个模拟实现,是因为这个类的行为太复杂,无法使用mockito进行模拟,因为它本身需要多个其他模拟 我无法确定如何将这个模拟实现注入到服务中 下面是一个最简单的例子: @Service public class ServiceIWantToTestImpl implements ServiceIWantToTest{ @Autowired ComplicatedDe

我想用我专门为测试而创建的类的模拟实现替换spring boot应用程序中的一个自动连接的服务类

我之所以选择创建这个模拟实现,是因为这个类的行为太复杂,无法使用mockito进行模拟,因为它本身需要多个其他模拟

我无法确定如何将这个模拟实现注入到服务中

下面是一个最简单的例子:

@Service
public class ServiceIWantToTestImpl implements ServiceIWantToTest{

    @Autowired
    ComplicatedDependency complicatedDependency;

    @Override
    public void methodUsingDependency(){
        String string = complicatedDependency.doSomething();
        System.out.println(string);
    }

}


public class MockComplicatedDependency implements ComplicatedDepencency{

    public MockComplicatedDependency(...){
        // Inject other mocked objects into this mock
    }

    public String doSomthing(){
        // This would be a mocked version of this function for testing
        return "test";
    }

}

@RunWith(MockitoJUnitRunner.class)
public class TestingTheService(){
    @InjectMock
    private static ServiceIWantToTest serviceIWantToTest = new ServiceIWantToTestImpl();

    @Mock
    ComplicatedDependency mockComplicatedDependency;

    @BeforeClass
    public static void init(){
        mockComplicatedDependency = new MockComplicatedDependency(...);
    }

    @Test
    public void testAttempt(){
        serviceIWantToTest.methodUsingDependency();  // This method calls complicatedDependency.doSomething() which does not run the mocked version in MockComplicatedDependency which I wanted to inject, and would always return null instead of the "test" string I put in this example.
    }

}

您是否必须使用Mockito注释为测试中的类设置依赖项

如果这不是主要约束为什么不直接进行简单设置,并在
serviceiwanttoestimpl
类中为
compleddependence
字段引入构造函数或setter,并直接将测试设置中的依赖项设置为您喜欢的任何复杂依赖项,例如:

@Service
public class ServiceIWantToTestImpl implements ServiceIWantToTest {

    @Autowired
    ComplicatedDependency complicatedDependency;

    public ServiceIWantToTestImpl() {

    }

    public ServiceIWantToTestImpl(ComplicatedDependency complicatedDependency) {
        this.complicatedDependency = complicatedDependency;
    }

    @Override
    public void methodUsingDependency(){
        String string = complicatedDependency.doSomething();
        System.out.println(string);
    }
}

public class TestingTheService {

    private static ServiceIWantToTestImpl serviceIWantToTest;

    @BeforeClass
    public static void init(){
        serviceIWantToTest = new ServiceIWantToTestImpl(new MockComplicatedDependency());
    }

    @Test
    public void testAttempt() {
        serviceIWantToTest.methodUsingDependency();
    }

}
这是一种方式

要使它与Mockito一起工作,您可以使用@Spy而不是@Mock,如下所示:

@RunWith(MockitoJUnitRunner.class)
public class TestingTheService {

    @InjectMocks
    private static ServiceIWantToTestImpl serviceIWantToTest = new ServiceIWantToTestImpl();

    @Spy
    private static ComplicatedDependency complicatedDependency = new MockComplicatedDependency();

    @BeforeClass
    public static void init() {

    }

    @Test
    public void testAttempt() {
        serviceIWantToTest.methodUsingDependency();
    }

}

虽然这有点像黑客。我强烈建议您阅读@Spy注释的JavaDoc,并确保它的预期用途是您测试所真正需要的。

我按照您的建议尝试使用@Spy,效果很好。谢谢我真的不想仅仅为了测试而引入构造函数,我想让spring处理应用程序中的依赖注入。实际上,构造函数级注入是推荐的方法,字段级注入通常是不推荐的,Spring已经推荐构造函数注入十年了:。没有人应该再使用现场注射了。啊哈,非常有趣!谢谢你提供的信息,我是自学成才的程序员,所以我的知识有很多漏洞。