Spring Boot / JUnit 5 / Mockito – 在测试类中模拟依赖项

huangapple go评论62阅读模式
英文:

Spring Boot / JUnit 5 / Mockito - mocking dependencies in Test classes

问题

我尝试编写JUnit 5测试用例来测试Spring Boot API,但在测试类中遇到了依赖注入的问题。我希望测试ProfileController中的端点,该Controller有3个依赖项:ProfileService、ProfileModelAssembler(用于向JSON响应添加REST相关装饰,例如“链接”)和ModelMapper。在我的测试类中,我使用以下方式对它们进行了注释:

@InjectMocks
ProfileController profileController;

@Mock
ProfileService profileService;

@Mock
ProfileModelAssembler profileModelAssembler;

@Mock
ModelMapper modelMapper;

当我尝试运行测试时,由于ProfileService的依赖项未满足,它会报错("No qualifying bean of type x.ProfileService available")。

在我的ProfileController中,我尝试直接使用@Autowired注解这些字段(我知道这不是推荐的做法):

@Autowired
private ProfileService profileService;
@Autowired
private ProfileModelAssembler profileModelAssembler;
@Autowired
private ModelMapper modelMapper;

以及通过构造函数注入的方式:

@Autowired
public ProfileController(ProfileService profileService, ProfileModelAssembler profileModelAssembler, ModelMapper modelMapper) {
    this.profileService = profileService;
    this.profileModelAssembler = profileModelAssembler;
    this.modelMapper = modelMapper;
}

但无论哪种方式,错误都是一样的。我发现关于JUnit和Mockito的教程方法多种多样,各不相同,这让我感到困惑。我知道解决问题通常有多种方法,但我很惊讶于没有什么“首选”做法。是否有建议可以消除此错误,或者有哪些资源可以帮助我以“简单”的方式满足我的相对简单需求来学习JUnit/Mockito?

英文:

I am trying to write JUnit 5 tests for a Spring Boot API but running into problem with dependency injection in the Test class. I wish to test endpoints in the ProfileController, which has 3 dependencies: ProfileService, ProfileModelAssembler (to add REST-centric decorations to json response, e.g. "links") and ModelMapper. In my Test class, I have the following 3 annotated as shown:

@InjectMocks
ProfileController profileController;

@Mock
ProfileService profileService;

@Mock
ProfileModelAssembler profileModelAssembler;

@Mock
ModelMapper modelMapper;

When I try to run a test, it errors out instantiating the ProfileController due to unsatisfied dependency for the ProfileService ("No qualifying bean of type x.ProfileService available").

In my ProfileController, I have tried to @Autowire those fields directly (not recommended, I know):

@Autowired
private ProfileService profileService;
@Autowired
private ProfileModelAssembler profileModelAssembler;
@Autowired
private ModelMapper modelMapper;

as well as via constructor injection:

@Autowired
public ProfileController(ProfileService profileService, ProfileModelAssembler profileModelAssembler, ModelMapper modelMapper) {
    this.profileService = profileService;
    this.profileModelAssembler = profileModelAssembler;
    this.modelMapper = modelMapper;
}

Error is the same either way. Tutorials I have found for JUnit and Mockito are absolutely all over the place in approach, doing things radically different from one another. I know there are always multiple solutions to a problem, but I've been surprised at how little adherence to any sort of "preferred" practice there is. Any recommendations to eliminate this error or resources to which I could turn to learn JUnit/Mockito in a "simple" way for my relatively simple needs?

答案1

得分: 3

@Mock@InjectMocks注解与Spring无关,因此在ProfileController类中如何自动装配依赖项并不重要。从您收到的错误看,似乎您正在使用@SpringBootTest运行测试,这会启动应用程序上下文,因此您需要在ProfileService等上使用@MockBean注解,以便它们被注入到应用程序上下文中。

或者,您可以在不启动整个应用程序上下文的情况下进行基本单元测试,在这种情况下,@Mock@InjectMocks注解将按您期望的方式工作。只需确保正确初始化模拟对象。最简单的方法是在测试类上注释@ExtendWith(MockitoExtension.class)

英文:

@Mock and @InjectMocks annotations have nothing to do with Spring so it doesn't matter how you autowire the dependencies in the ProfileController class. From the error you got it looks like you are running the test with @SpringBootTest where the application context is started so you would need to use the @MockBean annotations on ProfileService and others in order for them to be injected into the application context.

Alternatively, you can have a basic unit test without starting the whole application context where @Mock and @InjectMocks annotations would work as you expect. Just make sure to properly initialize the mocks. The easiest way would be to annotate the test class with @ExtendWith(MockitoExtension.class)

huangapple
  • 本文由 发表于 2023年6月16日 02:59:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76484746.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定