【发布时间】:2017-06-28 03:28:39
【问题描述】:
谁能告诉我应该如何测试这两种方法:
public boolean deleteUser(Principal principal) {
if (findLoggedInUser(principal) != null) {
userRepository.delete(findLoggedInUser(principal));
return true;
}
return false;
}
public User findLoggedInUser(Principal principal) {
return findUserbyUsername(principal.getName());
}
问题是我正在使用具有基本身份验证的当前登录用户并且不知道如何以及是否可以模拟这些委托人。有没有办法做到这一点?这些方法在我的服务层中,所以也许我不能进行单元测试,而我只能进行集成测试,因为这些方法大量使用 DB?
编辑 1: 我更改的测试类:
public class UserServiceBeanTest {
@Spy
@InjectMocks
private UserServiceBean userServiceBean;
@Mock
private UserRepository userRepository;
@Mock
private Principal principal;
@Mock
private PasswordEncoder passwordEncoder;
@Mock
private User userStub;
private String defaultName = "user";
private String defaultPassword = "password";
private String defaultEmail = "example@example.com";
@Before
public void init() {
MockitoAnnotations.initMocks(this);
}
@Test
public void shouldReturnTrue_whenUserDeleted() {
//given
when(principal.getName()).thenReturn(defaultName);
when(userServiceBean.findLoggedInUser(principal)).thenReturn(userStub);
// when
boolean removed = userServiceBean.deleteUser(principal);
//then
assertTrue(removed);
verify(userRepository, times(1));
}
@Test
public void shouldReturnFalse_whenUserNotFound() {
//given
when(principal.getName()).thenReturn(defaultName);
when(userServiceBean.findLoggedInUser(principal)).thenReturn(null);
//when
boolean removed = userServiceBean.deleteUser(principal);
//then
assertFalse(removed);
verify(userRepository, times(0));
}
}
我现在遇到了这些错误:
org.mockito.exceptions.misusing.UnfinishedVerificationException:
失踪
g method call for verify(mock) here:
-> at com.doublemc.services.UserServiceBeanTest.shouldReturnTrue_whenUserDeleted(UserServiceBeanTest.java:63)
Example of correct verification:
verify(mock).doSomething()
Also, this error might show up because you verify either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
Mocking methods declared on non-public parent classes is not supported.
at com.doublemc.services.UserServiceBeanTest.init(UserServiceBeanTest.java:48)
编辑 2: 这是我的 UserServiceBean 类:
package com.doublemc.services;
import com.doublemc.domain.ToDoItem;
import com.doublemc.domain.User;
import com.doublemc.repositories.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
import java.security.Principal;
@Service
@Transactional
public class UserServiceBean {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
@Autowired
UserServiceBean(UserRepository userRepository, PasswordEncoder passwordEncoder) {
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
}
public User saveUser(User user) {
User newUser = new User();
newUser.setUsername(user.getUsername());
newUser.setEmail(user.getEmail());
newUser.setPassword(passwordEncoder.encode(user.getPassword()));
return userRepository.save(newUser);
}
public boolean userExists(User user) {
return userRepository.findByUsername(user.getUsername()) != null;
}
public Iterable<ToDoItem> getAllToDoItems(User user) {
return user.getToDoItems();
}
public boolean deleteUser(Principal principal) {
if (findLoggedInUser(principal) != null) {
userRepository.delete(findLoggedInUser(principal));
return true;
}
return false;
}
public User findLoggedInUser(Principal principal) {
return userRepository.findByUsername(principal.getName());
}
}
这是我的 UserRepository:
public interface UserRepository extends CrudRepository<User, Long> {
User findByUsername(String username);
}
编辑 6:我为自己创建了另外三个测试:
@Test
public void shouldReturnUser_whenPassedUser() {
// given
when(userRepository.save(any(User.class))).thenReturn(new User(defaultName, defaultPassword, defaultEmail));
// when
User savedUser = userServiceBean.saveUser(userStub);
// then
assertNotNull(savedUser);
verify(userRepository, times(1)).save(any(User.class));
}
@Test
public void shouldReturnTrue_whenUserExists() {
// given
when(userStub.getUsername()).thenReturn(defaultName);
when(userRepository.findByUsername(userStub.getUsername())).thenReturn(userStub);
// when
boolean exists = userServiceBean.userExists(userStub);
// then
assertTrue(exists);
verify(userRepository, times(1)).findByUsername(defaultName);
}
@Test
public void shouldReturnFalse_whenUserNotFoundByUsername() {
// given
when(userStub.getUsername()).thenReturn(defaultName);
when(userRepository.findByUsername(userStub.getUsername())).thenReturn(null);
// when
boolean exists = userServiceBean.userExists(userStub);
// then
assertFalse(exists);
verify(userRepository, times(1)).findByUsername(defaultName);
}
以下是经过测试的方法: UserServiceBean.saveUser:
public User saveUser(User user) {
User newUser = new User(user.getUsername(), user.getEmail(), passwordEncoder.encode(user.getPassword()));
return userRepository.save(newUser);
}
UserServiceBean.userExists:
public boolean userExists(User user) {
return userRepository.findByUsername(user.getUsername()) != null;
}
【问题讨论】:
-
测试一下他们呢?
-
好吧,如果例如 deleteUser 方法实际上删除了一个用户 - 这就是测试的目的,对吧?
-
不,您不应该测试
deleteUser是否确实删除了用户:您应该检查它是否使用您期望的参数调用了userRepository.delete。是否真正删除用户取决于userRepository的实现。 -
因此,如果我已经测试了存储库,那么我不必在我的服务层中测试与控制器和存储库通信的任何其他方法?
-
什么是
Principal?有几种类型命名。
标签: java spring unit-testing spring-security mockito