春天已经到来,为什么我们不来谈谈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/