我有一个使用多个服务的控制器类。我为该控制器编写了一个测试,例如:
@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 {
注释?它适用于我的情况吗?
答案 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})