你试图做的不是单元测试
如果测试返回的对象是否为特定具体类的实例,则不是单元测试。您正在进行集成测试。虽然集成测试很重要,但它不是一回事。
在单元测试中,您只需要测试对象本身。如果对返回的抽象对象的具体类型进行断言,则是对返回对象的实现进行测试。
一般对象的单元测试
在单元测试时,您需要断言四件事:
- 查询的返回值(非 void 方法)是您期望它们的样子。
- 命令的副作用(void 方法)会按预期修改对象本身。
- 接收发送到其他对象的命令(这通常使用模拟来完成)。
此外,您只想测试可以从对象实例(即公共接口)观察到的内容。否则,您将自己绑定到一组特定的实现细节。这将要求您在这些详细信息更改时更改测试。
单元测试工厂
在工厂上进行单元测试确实无趣,因为您对返回的查询对象的行为不感兴趣。该行为(希望)在其他地方进行测试,大概是在对该对象本身进行单元测试时。您只对返回的对象是否具有正确的类型感兴趣,如果您的程序编译,则可以保证这一点。
由于工厂不会随时间而变化(因为那样它们将是“Builders”,这是另一种模式),因此没有要测试的命令。
工厂负责实例化对象,因此它们不应依赖其他工厂来为其执行此操作。它们可能依赖于生成器,但即便如此,我们也不应该测试生成器的正确性,而应该测试生成器是否收到消息。
这意味着,您只需在 Factories 上测试它们是否将消息发送到它们所依赖的对象即可。如果您使用依赖关系注入,这几乎是微不足道的。只需模拟单元测试中的依赖项,并验证它们是否收到消息。
单元测试工厂摘要
- 不要测试返回对象的行为或实现细节!您的工厂不负责对象实例的实现!
- 测试是否接收到依赖项的命令。
就是这样。如果没有依赖项,则无需测试任何内容。除了可能断言返回的对象不是引用。null
集成测试工厂
如果您要求返回的抽象对象类型是特定具体类型的实例,则属于集成测试。
这里的其他人已经回答了如何使用运算符执行此操作。instanceof