在Spring项目中进行测试-使用Mockito将存储库注入服务

时间:2018-07-26 07:06:13

标签: java spring testing mockito

我试图了解如何在 Spring 项目中使用 Mockito ,但是我对以下内容有些困惑:

我将要使用真实的(内存中的)存储库测试服务。我在嘲笑该服务正在使用的所有其他对象。如果我理解正确,将模拟使用 @Mock 注释对象,使用 @Spy 使用真实对象以及使用 @InjectMocks 这些注释对象的“自动装配”。但是,我认为我误会了 @Spy ,因为以下代码无法正常工作(似乎插入了模拟对象,似乎没有db交互,也没有出现NullPointerException):

@SpringBootTest
@RunWith(SpringRunner.class)
public class UserServiceTests {

    @Spy
    @Autowired
    private UserRepository userRepository;

    @Mock
    private MessageService messageService;

    @InjectMocks
    private UserService userService = new UserServiceImpl();

    @Test
    public void testUserRegistration() {
        userService.registerUser("test@test.test");

        Assert.assertEquals("There is one user in the repository after the first registration.", 1, userRepository.count());
    }

}

如果我删除 @Spy 批注,并使用反射将存储库插入服务中,那么它将起作用:

ReflectionTestUtils.setField(userService, "userRepository", userRepository);

这似乎很不方便,我很确定 @Spy 可以做到这一点。谁能指出我的缺失/误解?

编辑:还有一件事情-使用 @Spy 批注,保存时我没有得到NullPointerException,但似乎插入了一个模拟对象,而不是真正的对象。存储库。

编辑2:我认为这是我困惑的答案:

SpringBoot Junit bean autowire

1 个答案:

答案 0 :(得分:1)

问题在于您可能@Autowire UserService中的某些服务/存储库 像这样:

public class UserServiceImpl() {

  @Autowired
  private UserRepository userRepository;
  @Autowired
  private MessageService messageService;

  // ... all the stuff
}

Mockito尝试通过不可用的构造函数或setter注入模拟。 尝试重新设计类UserServiceImpl,使其具有类似以下的构造函数:

public class UserServiceImpl() {

  private final UserRepository userRepository;
  private final MessageService messageService;

  @Autowired
  public UserServiceImpl(UserRepository userRepository, MessageService messageService) {
    this.userRepository = userRepository;
    this.messageService = messageService;
  }

比起您可以使用构造函数使用这些模拟实例化@Before中的服务。