为接口或每个实现编写单元测试?

sta*_*app 4 java unit-testing mockito

我有一个 Java 接口和几个实现。现在我想使用 Mockito 编写单元测试用例。

我的问题是,我应该为每个实现编写模拟测试用例还是只为接口编写模拟测试用例?这种情况下的最佳实践是什么?我希望我的问题有意义。如果我遗漏了什么,请纠正我。

课程详情:

interface MessageQueue {
    add()
    poll()
    size()
}

class InMemoryMessageQueue implements MessageQueue {
    add() {
        //implementation
    }
    poll() {
        //implementation
    }
    size() {
        //implementation
    }
}

class FileSystemMessageQueue implements MessageQueue {
    add() {
        //implementation
    }
    poll() {
        //implementation
    }
    size() {
        //implementation
    }
}
Run Code Online (Sandbox Code Playgroud)

目前我只有使用 Mockito 的接口的单元测试用例MessageQueue

Flo*_*etz 6

听起来您在这里混淆了一些细节,因为如果没有更多细节,“模拟测试用例”这个词没有多大意义......

首先,如果您有接口的三个实现,那么最佳实践是测试所有这三个实现。

只要您的实现没有依赖项,就根本不涉及任何模拟,因为......

其次,模拟用于测试依赖关系。例如:

您的实现 #2 必须从数据库加载数据。为此,它使用一个类的实例,我们称之为DatabaseAccessor。通过调用此DatabaseAccessor对象的方法,它从数据库获取数据。

现在,如果您想对实现 #2 进行单元测试,您实际上并不需要数据库,因为这样做会带来很多问题。例如,如果数据库已关闭或处于不正确的状态,即使您实际想要测试的实现 #2 完全没问题,您的测试也会失败。

这就是模拟的用武之地。DatabaseAccessor您可以模拟一个对象,而不是使用实际的对象。换句话说,您创建一个看起来像 a 的对象DatabaseAccessor,但实际上并不访问 Ddtabase。这种模拟的行为是可以配置的,例如,如果调用一个方法,模拟会返回一些有用的测试数据(同样,无需实际调用数据库,您只需告诉它“如果调用方法 X,做这个”)。

这样,您可以专注于仅测试您的单元 - 实现 #2 - 而不必担心它的所有依赖项。这些人会被嘲笑,但你知道,他们会表现得像他们应该的那样。

是的,使用 Mockito,您可以模拟实现和接口,但最佳实践是无论如何都使用接口。对于进一步的问题,我建议提供有关您的课程的更多详细信息。