java - 如何使用mockito对图节点进行单元测试?

标签 java unit-testing mockito directed-graph

考虑下面的类:

public class Node {
    private final Collection<Node> mDependants = new ArrayList<>();
    private Node mDependency;

    public void initialize(final Node node) {
        // complex code that might call registerDependency;
    }

    private void registerDependency(final Node node) {
        mDependency = node;
        node.registerDependent(this);
    }

    private void registerDependent(final Node node) {
        mDependants.add(node);
    }
}

然后是单元测试:

import static org.mockito.Mockito.mock;

public class NodeTest {
    private Node mTarget;
    private Node mDependent;

    @Before
    public void setUp() {
        mTarget = new Node();
        mDependent = mock(Node.class);
    }

    @Test
    public void test() {
        mTarget.initialize(mDependent);
    }
}

由于registerDependent是私有(private)的,mockito实际上不会模拟它。由于mTarget实际上是一个真实的实例,因此当通过initialize执行registerDependency方法时,它会尝试执行mock上的私有(private)方法registerDependent。作为模拟的模拟将不会被初始化,并且 mDependants 实际上将为 null,从而导致 mDependats.add(node) 上出现 NullPointerException。

测试这个的正确方法应该是什么?我应该使用两个真实节点而不是模拟节点吗?我应该公开这些方法以允许对该方法进行模拟吗?我还缺少另一个选项吗?最终 Node 节点

最佳答案

因为这是对 Node 的测试,所以尽可能避免模拟 Node。它使得测试模拟框架是否正常工作或者您的规范是否正确定义变得非常容易,而不是测试您的实现是否正确。

我很喜欢 JB Nizet 如何输入 his SO answer here :如果您正在构建炸弹雷管,您的频繁测试应该使用真实雷管和模拟炸弹。模拟应该针对被测系统的依赖项协作者,而不是针对被测系统本身。

如果您的 Node 是一个接口(interface),并且您的 NodeImpl 实现可以接受任何 Node 作为依赖项,那么使用模拟 Node 可能更有意义,因为您可以传入具有不同实现的 Node,而这些实现可能还不存在,并且因为当您将自己限制在模拟接口(interface)时,Mockito 的许多陷阱就会消失。但是,由于 Node 及其依赖的 Node 是相同的具体类并且依赖于私有(private)实现细节,因此您在使用真实实例时可能会取得更大的成功。

此外,这些节点不太可能涉及繁重的服务层或其他容易被 mock 的依赖项,并且毫无疑问该节点是否表现良好:您可以在相邻的测试中看到它。

(旁白:有一些技术可以模拟被测系统中的各个方法——“部分模拟”——但是当您不使用遗留代码或繁重的服务时,也最好避免这些技术。)

关于java - 如何使用mockito对图节点进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32618106/

相关文章:

java - 2 个互斥的InputComponents 引用相同的Field 则更新相同的字段两次

java - Apache HttpClient 超时

c# - 从 UWP 调用的 PCL 汇编代码中的 MissingManifestResourceException

java - 使用 powerMockito 在 Runnable 中模拟 new()

java - 如何将 SpringBootTest 与 Web 安全和 Service usnig Junit5 和 Mockito 结合使用?

java - 如何复制远程目录中的所有文件?

android - 从 Android Studio 运行 Kotlin Koans 测试

unit-testing - 在 $http 的错误函数中抛出错误导致 $digest 已经在单元测试中进行

unit-testing - 未注入(inject)模拟对象

Java : Sort a List<Point> with neighbour