在 junit mockito 中使用 Optional.of 时出现未找到错误

I got the not found error when using Optional.of in junit mockito

我正在尝试在 junit mockito 中实现一个简单的测试以从数据库中获取记录。 这是我的测试 class:

@ExtendWith(MockitoExtension.class)
class AddressControllerTest {



    @Mock
    AddressRepository addressRepository;

    @InjectMocks
    AddressServiceImpl addressServiceImpl;


    @Test
    void findByIdTest(){
        Address myAddress = new Address();
        when(addressRepository.findById(12)).thenReturn(Optional.of(myAddress));

        Address theAddress = addressServiceImpl.findById(12);
        assertNotNull(theAddress);
    }
}

但我收到此错误消息: “找不到合适的方法 thenReturn(java.util.Optional)”

如果我删除“Optional.of”并仅使用该对象,则不会出现任何错误。

我的问题是:

这是我的 pom.xml:

<properties>
            <java.version>1.11</java.version>
            <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
            <junit-platform.version>5.7.0</junit-platform.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.thymeleaf.extras</groupId>
                <artifactId>thymeleaf-extras-springsecurity5</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
    
            <dependency>
                <groupId>org.postgresql</groupId>
                <artifactId>postgresql</artifactId>
                <scope>runtime</scope>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</artifactId>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter-api</artifactId>
                <version>${junit-platform.version}</version>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.junit.platform</groupId>
                <artifactId>junit-platform-commons</artifactId>
                <version>1.7.0</version>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter-engine</artifactId>
                <version>${junit-platform.version}</version>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.mockito</groupId>
                <artifactId>mockito-core</artifactId>
                <version>3.6.0</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.mockito</groupId>
                <artifactId>mockito-junit-jupiter</artifactId>
                <version>3.6.0</version>
                <scope>test</scope>
            </dependency>
    
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>

why did I get that error?

你想在这里嘲笑 addressRepository.findById(12)。当调用 addressRepository.findById(12) 时,你说它应该 return Optional.of(myAddress)。问题是,它不可能 return Optional.of(myAddress),这是一个 Optional<Address>findById 似乎声明为 return Address,而不是 Optional<Address>

当您删除 Optional.of 时,您是在告诉它 return 只是 myAddress,它当然可以做到。 myAddressAddress 类型,findById 声明为 return 和 Address

就所涉及的类型而言,when接受一个T和return一个OngoingStubbing<T>,它有一个方法叫做thenReturn,它需要 T。由于您将 Address 传递给 whenT 被推断为 Address,因此 thenReturn 也接受了 Address

what's the difference in using or not using Optional.of?

如您所见,使用 Optional.of 会给您一个错误,而不使用它则不会。在这里使用 Optional.of 没有意义,除非 findById 声明为 return Optional<Address>.

你的配置有问题,我安装了类似的测试并得到了正确的响应。你能分享你的配置吗?

地址库

@Repository
public interface AddressRepository extends CrudRepository<Address, Integer> {

}

AddressServiceImpl

@Service
@RequiredArgsConstructor
public class AddressServiceImpl implements AddressService {

    private final AddressRepository addressRepository;
    
    public Address findById(final Integer id) {
        return addressRepository.findById(id).get();
    }

}

pom.xml

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

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

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

尝试使用:

when(addressRepository.findById(Mockito.eq(12))).thenReturn(Optional.of(myAddress));

改为:

when(addressRepository.findById(12)).thenReturn(Optional.of(myAddress));