在Spring Boot 2应用程序的JUnit 5测试中模拟自动连接依赖项

时间:2017-10-16 14:16:16

标签: spring spring-boot junit junit5

考虑下面的测试类:

public class SomeClass {

    @Autowired
    private SomeDependency someDependency;

    public int inc(int i) {
        someDependency.doSomething();
        return i + 1;
    }

}

如何在Spring Boot 2(someDependency)应用程序的JUnit 5(5.0.1)测试中模拟(最好使用Mockito)2.0.0.M2?当我尝试调用SomeClass#inc(int)时,它会产生NullPointerException,因为未注入自动连接的依赖项。

1 个答案:

答案 0 :(得分:5)

Mockito 1 runner(MockitoJUnitRunner类)不适用于运行JUnit 5测试。

所以用:

注释你的班级
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class) 
public class MyJUnit5Test {

无效。

为了能够使用@Mock注释,您可以在每次测试之前调用:

 MockitoAnnotations.initMocks(this);

在使用JUnit 5 @BeforeEach注释的方法中 但是从现在开始,在每个JUnit测试类中不重复这种预处理的更好的替代方法是使用MockitoExtension class provided by the mockito-junit-jupiter dependency

代码示例

假设SomeDependency类声明为:

@Component
public class SomeDependency {

    public String returnThat() {
        return "that";
    }
}

你可以在单元测试中以这种方式模仿依赖:

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;

import davidhxxx.example.angularsboot.SomeDependency;

@ExtendWith(MockitoExtension.class)    
public class SomeClassTest {

    @Mock
    SomeDependency someDependencyMock;

    private SomeClass someClass;

    @BeforeEach
    public void setup(){
      someClass = new SomeClass(someDependencyMock);
    }

    @Test 
    void myFirstTest() {
      Mockito.when(someDependencyMock.returnThat()).thenReturn("mock result");
      Assertions.assertEquals("mock result", someClass.inc());
    }

}

请注意,SomeClass必须提供一种设置其SomeDependency依赖关系的方法 您应该添加一个接受。的实例的构造函数 使用setter也是一种提供可变性的方法。

pom.xml要求

1)您可以在继承的依赖项中添加包含Mockito的the spring-boot-starter-test依赖项和其他有用的东西:

<dependencies>
    ...
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
   ...
</dependencies>

还添加junit-jupiter-engine依赖项以及所需的所有其他可选JUnit 5依赖项:

<dependencies>
    ...
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-junit-jupiter</artifactId>
        <version>2.18.0</version> <!-- version to specify as not provided by Spring Boot dependencies -->
        <scope>test</scope>
    </dependency>
</dependencies>

您不需要为junit-jupiter-engine工件指定版本,但您可能需要其他JUnit 5依赖项,例如junit-jupiter-params
希望在下一版本的Spring Boot中不再需要这样做。

2)注意:如果你使用的是Spring Boot版本 2.20版maven-surefire-plugin它不起作用。因此,您必须覆盖maven-surefire-plugin插件配置,以指定与JUnit 5兼容的版本(即2.19或2.21及更高版本)。
例如,2.0.0.M5版本的Spring Boot提取了maven-surefire-plugin:2.20,因此需要重新配置插件,如下所示:

    <plugins>
        ...
        <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.19</version>
            <dependencies>
                <dependency>
                    <groupId>org.junit.platform</groupId>
                    <artifactId>junit-platform-surefire-provider</artifactId>
                    <version>1.0.0</version>
                </dependency>
            </dependencies>
        </plugin>
     ...
   <plugins>

它会生成一个Maven警告:

  

覆盖托管版本2.20.1 for maven-surefire-plugin

好消息:从2.0.1.RELEASE版本的Spring Boot中解决了这个问题,因为maven-surefire-plugin版本已更新为使用2.21.0及更高版本来解决问题。