我是一个后端世界的FEE新手,正在用Sping Boot 构建一个实践项目。我有一个服务,它使用一个存储库保存一个带有用户名和密码的“Admin”对象,该服务有一个方法来验证请求是否具有存储库的有效用户名/密码。当我用postman测试时,这个服务工作正常,但我的生命中我无法让测试工作。我是第一次使用junit/mockito,所以我想我是在错误地模拟我的仓库。我在服务的方法中有两个日志行,看起来像我的测试用例,当调用这个方法时,仓库用户名/密码不是我模拟的,而是仓库中用户名/密码的实际值。这导致我的测试用例失败。我的目标是让 * 在我的服务类中比较的存储库的mock * 用户名/密码。
下面是我的服务的validateIsAdmin方法中的两个日志行:log.info("username and password for repository is: " + adminRepository.getAdminUserName() + " | " + adminRepository.getAdminPassword()); log.info("Recieved admin auth request with {}", adminRequest.getUsername() + " | " + adminRequest.getPassword());
下面是我尝试测试的服务类:
package com.couvq.readinglist.service;
import com.couvq.readinglist.dto.AdminRequest;
import com.couvq.readinglist.dto.AdminResponse;
import com.couvq.readinglist.repository.AdminRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
@Log4j2
public class AdminAuthService {
private final AdminRepository adminRepository;
public AdminResponse validateIsAdmin(AdminRequest adminRequest) {
log.info("username and password for repository is: " + adminRepository.getAdminUserName() + " | " + adminRepository.getAdminPassword());
log.info("Recieved admin auth request with {}", adminRequest.getUsername() + " | " + adminRequest.getPassword());
// if username and password of request matches that of repository, isAdmin is true
if (adminRequest.getUsername().equals(adminRepository.getAdminUserName())
&& adminRequest.getPassword().equals(adminRepository.getAdminPassword())) {
return AdminResponse.builder()
.isAdmin(true)
.build();
} else {
return AdminResponse.builder()
.isAdmin(false)
.build();
}
}
}
这是我的测试案例
import com.couvq.readinglist.dto.AdminRequest;
import com.couvq.readinglist.dto.AdminResponse;
import com.couvq.readinglist.repository.AdminRepository;
import com.couvq.readinglist.service.AdminAuthService;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
@SpringBootTest
@ExtendWith(MockitoExtension.class)
class ReadingListApplicationTests {
@Autowired
private AdminAuthService adminAuthService;
@Mock
private AdminRepository adminRepository;
@Test
public void validateIsAdminWithAdminUserNameAndPasswordReturnsTrueResponse() {
when(adminRepository.getAdminUserName()).thenReturn("username");
when(adminRepository.getAdminPassword()).thenReturn("password");
AdminRequest request = AdminRequest.builder()
.username("username")
.password("password")
.build();
AdminResponse response = adminAuthService.validateIsAdmin(request);
AdminResponse expectedResponse = AdminResponse.builder()
.isAdmin(true)
.build();
assertEquals(expectedResponse, response);
}
}
下面是我从测试Assert中得到的输出:
org.opentest4j.AssertionFailedError:
Expected :AdminResponse(isAdmin=true)
Actual :AdminResponse(isAdmin=false)
有人对我如何正确地模拟这个存储库有什么建议吗?
2条答案
按热度按时间mmvthczy1#
只需使用@ExtendWith(MockitoExtension.class)并将@Autowired替换为@InjectMocks,这将把您的mock存储库类注入到服务中。
oug3syen2#
因为它是一个
@SpringBootTest
-整个Application Context
都是 Bootstrap 的,包括AdminRepository
和AdminAuthService
bean。如果测试是一个简单的单元测试,使用@Mock
就足够了。但是因为它是一个集成测试,并且AdminAuthService
是自动连接到测试中的,我们希望AdminRepository
也被注入到AdminAuthService
中。为了使依赖注入工作并能够模拟AdminRepository
,我们需要使用以下代码:此外,一旦这样做,
@ExtendWith(MockitoExtension.class)
就变得多余了。