@MockBeans 示例使用

mat*_*e00 6 spring spring-test spring-boot

我有一个使用多种服务的控制器类。我为该控制器编写了一个测试,例如:

@RunWith(SpringRunner.class)
@WebMvcTest(value = PurchaseController.class, secure = false)
public class PurchaseControllerTest {

    @MockBean
    private ShoppingService shoppingService;

    @MockBean
    private ShopRepository shopRepository;

    @MockBean
    private SomeOtherRepository someOtherRepository;

    @Autowired
    private MockMvc mockMvc;

// ... some tests goes here
Run Code Online (Sandbox Code Playgroud)

事情是,往往有很多这样的模拟,因此有很多行代码。我知道这可能是代码异味的迹象,但这不是我现在的重点。

我注意到还有一个@MockBeans注释有@Target(ElementType.TYPE). 所以我想我可以尝试:

@RunWith(SpringRunner.class)
@WebMvcTest(value = PurchaseController.class, secure = false)
@MockBeans(value = {ShoppingService.class, ShopRepository.class})
public class PurchaseControllerTest {
Run Code Online (Sandbox Code Playgroud)

但它没有事件编译。

我的问题是:我们如何使用@MockBeans注释?它适用于我的情况吗?

xyz*_*xyz 12

@MockBeans它只是@MockBeans乘法的可重复注释。如果您需要重用这个模拟 bean,您可以放入一个类/配置类。但是您需要使用 @Autowired您要模拟的服务。所以在你的情况下它应该是:

.....
@MockBeans({@MockBean(ShoppingService.class), MockBean(ShopRepository.class)})
public class PurchaseControllerTest {
  @Autowired
  ShoppingService shoppingService;
  @Autowired
  ShopRepository shopRepository;
.....
}
Run Code Online (Sandbox Code Playgroud)

@MockBeans它的主要思想只是@MockBean在一个地方重复。对我来说,它可能仅对您可以重用的某些配置/通用类有用。

@MockBean- 创建一个模拟,@Autowired- 是来自上下文的自动装配 bean,在您的情况下,它将 bean 标记/创建为模拟然后模拟bean 将注入您的自动装配字段。

所以,如果你有很多与自动装配领域@MockBeans(或多次@MockBean),你可以配置它是在一个地方(在模拟或不@MockBeans用于类级别),你不需要改变@Autowired@Mock你的测试类(像你情况下,如果您删除@MockBeans所有未模拟的自动装配 bean 将被自动装配为上下文中的 bean,如果您撤消移除,您将在模拟 bean(您在此注释中配置)中工作)。

如果你想避免一个类中的大量依赖,你可以将所有依赖提取到某个父类中,但是由于 java 不支持类的多重继承,所以它并不总是有帮助。

  • 谢谢。那么看起来利润并不多。我可以在课堂级别列出我所有的模拟,但无论如何我必须自动装配它们...... (2认同)

bor*_*ino 8

您的情况下最短的变体是@MockBean支持所需模拟类的多个值

@MockBean({ShoppingService.class, ShopRepository.class})
Run Code Online (Sandbox Code Playgroud)