如何修复 MockitoExtension.class 未解决的错误

How to fix MockitoExtension.class not resolved error

我最近从 JUnit4 迁移到了 JUnit5。我已经更新并编辑了我的 POM 文件(多个 POM,因为我的项目是一个多 Maven 项目)。

我的 IDE (IntellIj Idea) 似乎正在解析 JUnit 5 注释。它们都可用且功能齐全。

但是,当我尝试用 @ExtendWith(MockitoExtension.class) 注释 OwnerSDJpaServiceTest 时,IntellIj 一直告诉我它 “无法解析符号 'MockitoExtension'。

对我来说,看起来我缺少一些依赖项,但我已经看过 在 youtube 视频和一些文档中,我觉得一切都很好。所以我不知道真正的问题在哪里。

可能是我缺少依赖项或者 POM 文件配置错误。

如果您需要查看整个应用程序,请使用此 link 至 my GitHub repo

这是我的根 pom 文件:

 <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>

        <groupId>guru.springframework</groupId>
        <artifactId>sfg-pet-clinic</artifactId>
        <version>0.0.5-SNAPSHOT</version>

        <modules>
            <module>pet-clinic-data</module>
            <module>pet-clinic-web</module>
        </modules>

        <packaging>pom</packaging>

        <name>sfg-pet-clinic</name>
        <description>SFG Pet Clinic Project</description>

        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.3.RELEASE</version>
            <relativePath /> <!-- lookup parent from repository -->
        </parent>

        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF 8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
        </properties>

        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-release-plugin</artifactId>
                    <configuration>
                        <goals>install</goals>
                        <autoVersionSubmodules>true</autoVersionSubmodules>
                    </configuration>
                </plugin>
            </plugins>

        </build>

        <scm>
            <developerConnection>scm:git:https://github.com/sajmon2325/Spring-Pet-Clinic.git</developerConnection>
          <tag>HEAD</tag>
      </scm>

    </project>

这是我的宠物诊所数据 pom 文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>sfg-pet-clinic</artifactId>
        <groupId>guru.springframework</groupId>
        <version>0.0.5-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>

    <artifactId>pet-clinic-data</artifactId>

    <properties>
        <spring.boot.repackage.skip>true</spring.boot.repackage.skip>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.0.3</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
        <groupId>org.javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.23.1-GA</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                    <configuration>
                        <skip>true</skip>
                    </configuration>
                </execution>
            </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19.1</version>
                <dependencies>
                    <dependency>
                        <groupId>org.mockito</groupId>
                        <artifactId>mockito-junit-jupiter</artifactId>
                        <version>2.27.0</version>
                        <scope>runtime</scope>
                    </dependency>


                </dependencies>
            </plugin>

        </plugins>
    </build>
</project>

这是我的宠物诊所数据 pom 文件

  <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>sfg-pet-clinic</artifactId>
        <groupId>guru.springframework</groupId>
        <version>0.0.5-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>

    <artifactId>pet-clinic-data</artifactId>

    <properties>
        <spring.boot.repackage.skip>true</spring.boot.repackage.skip>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.0.3</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
        <groupId>org.javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.23.1-GA</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                    <configuration>
                        <skip>true</skip>
                    </configuration>
                </execution>
            </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19.1</version>
                <dependencies>
                    <dependency>
                        <groupId>org.mockito</groupId>
                        <artifactId>mockito-junit-jupiter</artifactId>
                        <version>2.27.0</version>
                        <scope>runtime</scope>
                    </dependency>


                </dependencies>
            </plugin>

        </plugins>
    </build>
</project>

最后是我的 pet-clinic-web pom 文件(可能缺少依赖项):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>sfg-pet-clinic</artifactId>
        <groupId>guru.springframework</groupId>
        <version>0.0.5-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>

    <artifactId>pet-clinic-web</artifactId>

    <properties>
        <!-- Web dependencies -->
        <webjars-bootstrap.version>3.3.6</webjars-bootstrap.version>
        <webjars-jquery-ui.version>1.11.4</webjars-jquery-ui.version>
        <webjars-jquery.version>2.2.4</webjars-jquery.version>
        <wro4j.version>1.8.0</wro4j.version>
    </properties>

    <dependencies>
        <dependency>
            <artifactId>pet-clinic-data</artifactId>
            <groupId>guru.springframework</groupId>
            <version>0.0.5-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- webjars -->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>webjars-locator-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>${webjars-jquery.version}</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery-ui</artifactId>
            <version>${webjars-jquery-ui.version}</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>${webjars-bootstrap.version}</version>
        </dependency>
        <!-- end of webjars -->

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>ro.isdc.wro4j</groupId>
                <artifactId>wro4j-maven-plugin</artifactId>
                <version>${wro4j.version}</version>
                <executions>
                    <execution>
                        <phase>generate-resources</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <wroManagerFactory>ro.isdc.wro.maven.plugin.manager.factory.ConfigurableWroManagerFactory</wroManagerFactory>
                    <cssDestinationFolder>${project.build.directory}/classes/static/resources/css</cssDestinationFolder>
                    <wroFile>${basedir}/src/main/wro/wro.xml</wroFile>
                    <extraConfigFile>${basedir}/src/main/wro/wro.properties</extraConfigFile>
                    <contextFolder>${basedir}/src/main/less</contextFolder>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.webjars</groupId>
                        <artifactId>bootstrap</artifactId>
                        <version>${webjars-bootstrap.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>org.mockito</groupId>
                        <artifactId>mockito-core</artifactId>
                        <version>2.23.4</version>
                    </dependency>
                </dependencies>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.0</version>
                <dependencies>
                    <dependency>
                        <groupId>org.mockito</groupId>
                        <artifactId>mockito-junit-jupiter</artifactId>
                        <version>2.27.0</version>
                        <scope>runtime</scope>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
</project>

这是我的测试class(在MockitoExtension.class中有未解析符号的问题):

package guru.springframework.sfgpetclinic.services.springdatajpa;

import guru.springframework.sfgpetclinic.repositories.OwnerRepository;
import guru.springframework.sfgpetclinic.repositories.PetRepository;
import guru.springframework.sfgpetclinic.repositories.PetTypeRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

import static org.junit.jupiter.api.Assertions.*;

@ExtendWith(MockitoExtension.class)
class OwnerSDJpaServiceTest {

    OwnerRepository ownerRepository;
    PetRepository petRepository;
    PetTypeRepository petTypeRepository;

    OwnerSDJpaService service;


    @BeforeEach
    void setUp() {

    }

    @Test
    void findByLastName() {
    }

    @Test
    void findAll() {
    }

    @Test
    void findById() {
    }

    @Test
    void save() {
    }

    @Test
    void delete() {
    }

    @Test
    void deleteById() {
    }
}

我希望注释被 IntellIj 识别,所以我可以使用 JUnit5 测试这个 class。

我已经通过编辑我的网络 pom.xml 文件解决了这个问题:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>sfg-pet-clinic</artifactId>
        <groupId>guru.springframework</groupId>
        <version>0.0.5-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>

    <artifactId>pet-clinic-web</artifactId>

    <properties>
        <!-- Web dependencies -->
        <webjars-bootstrap.version>3.3.6</webjars-bootstrap.version>
        <webjars-jquery-ui.version>1.11.4</webjars-jquery-ui.version>
        <webjars-jquery.version>2.2.4</webjars-jquery.version>
        <wro4j.version>1.8.0</wro4j.version>
    </properties>

    <dependencies>
        <dependency>
            <artifactId>pet-clinic-data</artifactId>
            <groupId>guru.springframework</groupId>
            <version>0.0.5-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--<dependency>-->
        <!--<groupId>org.projectlombok</groupId>-->
        <!--<artifactId>lombok</artifactId>-->
        <!--<optional>true</optional>-->
        <!--</dependency>-->

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- webjars -->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>webjars-locator-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>${webjars-jquery.version}</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery-ui</artifactId>
            <version>${webjars-jquery-ui.version}</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>${webjars-bootstrap.version}</version>
        </dependency>
        <!-- end of webjars -->

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <scope>test</scope>
        </dependency>
        <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.22.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>ro.isdc.wro4j</groupId>
                <artifactId>wro4j-maven-plugin</artifactId>
                <version>${wro4j.version}</version>
                <executions>
                    <execution>
                        <phase>generate-resources</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <wroManagerFactory>ro.isdc.wro.maven.plugin.manager.factory.ConfigurableWroManagerFactory</wroManagerFactory>
                    <cssDestinationFolder>${project.build.directory}/classes/static/resources/css</cssDestinationFolder>
                    <wroFile>${basedir}/src/main/wro/wro.xml</wroFile>
                    <extraConfigFile>${basedir}/src/main/wro/wro.properties</extraConfigFile>
                    <contextFolder>${basedir}/src/main/less</contextFolder>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.webjars</groupId>
                        <artifactId>bootstrap</artifactId>
                        <version>${webjars-bootstrap.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.0</version>
            </plugin>
        </plugins>
    </build>
</project>

我在一个简单的测试项目中遇到了同样的问题,结果我只添加了 core artifact:

org.mockito:mockito-core 

我还需要添加 one that contains the extension for jUnit5:

org.mockito:mockito-junit-jupiter

将此添加到您的测试文件夹中 MokitoExtension.java

package com.pluralsight.tddjunit5;

 import org.junit.jupiter.api.extension.ExtensionContext;
 import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
 import org.junit.jupiter.api.extension.ExtensionContext.Store;
 import org.junit.jupiter.api.extension.ParameterContext;
 import org.junit.jupiter.api.extension.ParameterResolver;
 import org.junit.jupiter.api.extension.TestInstancePostProcessor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;

 import java.lang.reflect.Parameter;

 import static org.mockito.Mockito.mock;

public class MockitoExtension
    implements TestInstancePostProcessor, ParameterResolver {

@Override
public void postProcessTestInstance(Object testInstance,
        ExtensionContext context) {
    MockitoAnnotations.initMocks(testInstance);
}

@Override
public boolean supportsParameter(ParameterContext parameterContext,
        ExtensionContext extensionContext) {
    return parameterContext.getParameter().isAnnotationPresent(Mock.class);
}

@Override
public Object resolveParameter(ParameterContext parameterContext,
        ExtensionContext extensionContext) {
    return getMock(parameterContext.getParameter(), extensionContext);
}

private Object getMock(Parameter parameter,
        ExtensionContext extensionContext) {
    Class<?> mockType = parameter.getType();
    Store mocks = extensionContext
            .getStore(Namespace.create(MockitoExtension.class, mockType));
    String mockName = getMockName(parameter);

    if (mockName != null) {
        return mocks.getOrComputeIfAbsent(mockName,
                key -> mock(mockType, mockName));
    } else {
        return mocks.getOrComputeIfAbsent(mockType.getCanonicalName(),
                key -> mock(mockType));
    }
}

private String getMockName(Parameter parameter) {
    String explicitMockName = parameter.getAnnotation(Mock.class).name()
            .trim();
    if (!explicitMockName.isEmpty()) {
        return explicitMockName;
    } else if (parameter.isNamePresent()) {
        return parameter.getName();
    }
    return null;
}

}

我和 Gradle 有同样的问题。 MockitoExtension class 实际上在 mockito-junit-jupiter.jar 文件中,因此不需要 mockito-core。请参阅下面的屏幕截图:

这是我的 Gradle 文件的屏幕截图:

这是一篇可能有帮助的文章中的 link:https://www.vogella.com/tutorials/Mockito/article.html

如果您使用的是 Junit5,则需要包含此依赖项 org.mockito:mockito-junit-jupiter。 但是,对于 Junit4,您不需要使用此扩展,并且可以通过使用 Junit4 的 @RunWith 和 MockitoJUnitRunner.class 来实现相同的模拟行为。但在 Junit5 中,没有规则和赛跑者。因此您不能在 Junit5 中使用 @RunWith(MockitoJUnitRunner.class) 或规则。

在我的pom.xml中(我留给了version如果已经用于其他依赖)。

    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-junit-jupiter</artifactId>
    </dependency>

但是,还是没有找到class!

在我的 class 中,我正在测试:

import org.junit.jupiter.api.extension.ExtendWith;

@ExtendWith(org.mockito.junit.jupiter.MockitoExtension.class)
public class MyClassTest {
    //...
}

它不再要求导入....

然后,我手动导入,然后 Secondary Click -> Source -> Organize Imports.

import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
public class MyClassTest {
    //...
}