春天已经到来,为什么我们不来谈谈Spring的MockBean呢?Orzbihon这位大神指出了MockBean是一种反模式,究竟哪些理由让他对MockBean看不上眼呢?下面一起来了解一下吧!
MockBean的定义
MockBean是Spring框架中的一个注解,用来模拟bean,以便在测试过程中使用。MockBean允许你借助框架的Mockito库轻松地创建模拟对象。这意味着,你可以创建一个模拟实现并将其注入到Spring管理的bean中,从而测试这个bean的行为,而不是依赖于Spring启动后的实际实现。
为什么MockBean是一个反模式
虽然MockBean的确有很多好处,让测试更加简单和快速,但是它也有一个明显的反模式暗示,那就是让我们的代码更加脆弱。这是一个比较糟糕的方面,会导致测试错误误报,代码重构变得更加昂贵,甚至是越来越难以理解。
我们来看一个例子:
假设某个Controller使用了一个服务,该服务基于RestTemplate与外部API交互:
@RestController
@RequestMapping(“/api”)
public class SampleController {
@Autowired
private SampleService sampleService;
// …
}
@Service
public class SampleService {
private RestTemplate restTemplate;
@Autowired
public SampleService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
// …
}
但在测试时,仍然需要发出HTTP请求,这显然是我们避免的。解决这个问题的一种方法是模拟RestTemplate,因此我们可以避免调用外部API。为此,我们可以使用MockBean:
@SpringBootTest(classes = { SampleController.class, SampleService.class })
class SampleControllerTest {
@Autowired
private SampleController controller;
@MockBean
private RestTemplate restTemplate;
// …
}
这里呢,我们尝试在测试代码中模拟掉RestTemplate的实现,让测试变得更加快捷高效。但这个解决方案也会带来很多问题:
– 首先,MockBean需要特定的Spring上下文,这可能使测试套件的管理和设置变得更加麻烦。
– 其次,MockBean在测试中被多次使用,可能会在多个类和测试的上下文之间共享,从而导致代码的侵入性和耦合度增加。
– 最后,MockBean本质上是一种打补丁的解决方案,它使代码变得电灯泡或者说脆弱,并使测试可能出现错误的机会增加了。
结论
总之,Spring的MockBean确实是一个反模式。有很多优秀的替代方案,例如使用真正的实际对象,或者在依赖注入时编写更加高质量的代码。记住,如果你从代码的角度看起来可以替换它,不要使用MockBean。
了解更多有趣的事情:https://blog.ds3783.com/