@MockBeans示例使用

时间:2019-05-14 14:05:20

标签: spring spring-boot spring-test

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

@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

事实是,这些模拟往往会很多,因此会有很多代码行。我知道这可能是代码气味的迹象,但这不是我的意思。

我注意到还有一个@MockBeans的{​​{1}}注释。所以我想我可以尝试:

@Target(ElementType.TYPE)

但不会进行事件编译。

我的问题是:我们如何使用@RunWith(SpringRunner.class) @WebMvcTest(value = PurchaseController.class, secure = false) @MockBeans(value = {ShoppingService.class, ShopRepository.class}) public class PurchaseControllerTest { 注释?它适用于我的情况吗?

3 个答案:

答案 0 :(得分:2)

@MockBeans只是@MockBean的乘积的可重复注释。如果您需要重用这个模拟的bean,则可以放入一个class / config类。但是您需要使用@Autowired来模拟您要使用的服务。因此,您的情况应该是:

.....
@MockBeans({@MockBean(ShoppingService.class), MockBean(ShopRepository.class)})
public class PurchaseControllerTest {
  @Autowired
  ShoppingService shoppingService;
  @Autowired
  ShopRepository shopRepository;
.....
}

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

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

因此,如果您有很多带有@MockBeans(或乘以@MockBean)的自动连线字段,则可以配置它是否是模拟的,还是不在一个地方(对于类级别,在@MockBeans中)并且您不需要在测试类中将@Autowired更改为@Mock(例如,如果您删除@MockBeans,则所有未模拟的自动装配bean将自动装配为上下文中的bean,并且如果您撤消删除操作,则可以在模拟的Bean(在此注释中配置的Bean)中工作)。

如果您想避免在一个类中出现大量依赖关系,可以将所有依赖关系提取到某个父类中,但是由于Java不支持该类的多重继承,因此不一定总是有帮助。

答案 1 :(得分:2)

Javadoc说它用作

  

包含多个{@link MockBean}注释的容器注释。

所以你可以写

@MockBeans({@MockBean(ShoppingService.class), @MockBean(ShopRepository.class)})
public class PurchaseControllerTest {

@Autowire ShoppingService在这里工作

  

也可以    与Java 8对可重复注释

的支持结合使用
@MockBean(ShoppingService.class)
@MockBean(ShopRepository.class)
public class PurchaseControllerTest {

Java 8启用了可重复注释,并且出于兼容性原因,重复注释存储在Java编译器自动生成的容器注释@MockBeans中。为了使编译器执行此操作,您需要做两件事:

  • 可重复的@Repeatable(MockBeans.class)注释类型@MockBean
  • 包含注释类型@MockBeans

答案 2 :(得分:0)

您所用的最短变体是@MockBean,它支持必需的模拟类的多个值

@MockBean({ShoppingService.class, ShopRepository.class})