我正在Java Spring中编写一个由图层组成的应用程序。他们的责任是:
我在开发过程中一直在编写一些测试,现在我已经考虑过了,它们已经进行了一些集成测试。测试的一般流程可以描述为:
在每个步骤中,服务调用DAO层和保存/创建/获取的对象,然后对其进行操作,如果操作成功并且符合预期,则检查测试。
我正在考虑如何正确地进行单元测试。我知道我应该模拟测试服务所依赖的每个组件,这样我就可以“隔离”我想要测试的行为。但是,大多数服务方法实际上并没有“返回”任何东西,它们只是操纵实体。
我遇到的问题是 - 总是对应用程序的单元测试层/服务有意义,还是可以将它们作为一个整体进行测试?
附录
其中一种方法的示例。这个负责向组添加新用户。添加成员必须由该组的经理完成。所以逻辑是:
UIImage
服务并检查permissionHandler
用户是否在manager
中拥有足够的权限才能完成此操作group
。如果是,请抛出异常。newUser
服务以创建一个新的groupMemberHelper
对象,表示GroupMember
和user
之间的关联(以及有关该关联的更多信息)group
对象添加到论坛为了测试这个方法,我会跟踪GroupMember
,group
以及此方法影响的所有对象,并检查状态“之前”和“之后”是否是我期望的状态
在不依赖被调用服务的功能的情况下,我想不出另一种测试方法。我错了吗?
答案 0 :(得分:2)
示例中的方法向您显示您在服务中做了很多事情。这就是副作用所做的测试 - 他们展示了弱代码架构。尝试将验证逻辑移动到另一个bean,创建逻辑到工厂等等。您将拥有易于阅读,理解,维护和单元测试的代码。
答案 1 :(得分:2)
我知道我应该模拟测试服务所依赖的每个组件,以便我可以“隔离”。我想测试的行为。
这种广泛持有的观点是错误的。您总是必须模拟每个协作者。
在测试我的表示层时,我使用模拟数据层和真实(非模拟)服务层。
广泛持有的观点的错误是指定的行为和实现细节之间存在差异。您的测试应该测试指定的行为。他们不应该假设任何特定的实现细节。在大多数情况下,除了它的调用满足下层所施加的任何先决条件之外,没有指定高层与下层交互的方式。因此,如果您使用模拟的下层测试更高层,则模拟必须为其方法的每个提供正确的行为,因为您不知道更高层将调用哪些方法。这可以使正确的模拟对象与真实对象一样复杂。在这种情况下,使用模拟可以获得任何收益。
模拟数据层不是太繁重,因为您可以使用地图和列表而不是数据库将其实现为内存存储,并对所有服务层和表示层测试使用相同的模拟类。 / p>