首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UnitTesting帮助:使用存根?

UnitTesting帮助:使用存根?
EN

Stack Overflow用户
提问于 2016-11-30 16:46:48
回答 3查看 50关注 0票数 0

我有一个关于单元测试的问题。

我必须测试一个函数,称它为函数A,它接收B类的一个实例作为输入,并返回true或false。

现在,在我的测试中,我必须以某种方式创建一个对象来传递给函数A;我目前所做的是使用它的构造函数初始化类B,调用它的一些方法来填充它,创建正确的结构等等,然后将它传递给函数A。现在,我不确定这是一个好的模式:尤其是,如果B类的方法中有一个bug,或者我改变了它的接口,会发生什么?

所以我想我需要使用存根;但是编写一个具有B类基本相同结构的类似乎很奇怪;函数A最终也会与B类一起工作,所以如果我更改了B类的接口,那么函数A的测试应该崩溃,告诉我修改函数A以适应新的接口。

正确的模式是什么?

注:如果您认为这主要是基于意见,请将问题重新表述为:“按照”单元测试的艺术“所提倡的原则,在这里做什么是最好的?”--对于其他心智正常的人,请用更大的视角自由地写出答案。

编辑

我要澄清的是,函数A的唯一目的是以B类为例,验证是否满足了某个条件。现在,我可以创建一个存根来代替B类,但我不确定这是否有意义;这似乎是毫无意义的。另一方面,为了初始化B,我执行类似于classB.addData(RandomData)的操作;如果这段代码失败了会发生什么?当实际问题在B类的初始化过程中时,函数A的测试将出现错误

编辑2一些代码,可以更明确地显示该函数的功能。真正的代码是完全相同的,除了方法更复杂,但否则它是完全相同的

代码语言:javascript
复制
def functionA(objectB):
    return objectB.data < 10

def testFunctionA():
      objectB = classB()
      objectB.addData(19)      #Is this a problem or should I stub objectB?

      assert(functionA(objectB) is False)
EN

回答 3

Stack Overflow用户

发布于 2016-11-30 17:57:09

在我看来,单元测试工具箱中最强大的工具是依赖注入,这非常适合这里。

在构造对象时,它的所有协作对象都应该以接口引用的形式传递给它的构造函数。在您的情况下,要测试的单元是一个函数,但原理是相同的。以同样的方式将函数协作者对象传递给它。

如果您的测试对象仅通过接口与其他对象协作,则可以在单元测试中传递模拟对象。此外,像google模拟这样的框架可以非常方便地创建模拟,并在预期的交互易于理解的情况下编写干净的测试用例。

如果这就是你的意思,那么是的,这是一个很好的模式。

编辑:

这就是我编写测试函数的方式。

代码语言:javascript
复制
def functionA(objectB):
    return objectB.data < 10

def testFunctionA():
      objectB = fakeClassB()
      EXPECT_CALL(objectB, data).WillOnce(Return(19))
      assert(functionA(objectB) is False)

而不是传递一个真实的classB对象,而是传递一个fakeClassB对象。这使得测试取决于classB的接口,而不是classB的实际实现。失败的测试是由接口使用错误造成的,而不是一些实现细节n classB造成的。根据您正在使用的语言,我认为这可能是可能的,也可能不是。

另一个好处是构建复杂性。您可以在不构建classB实现的情况下构建测试函数。您只需要构建classB和fakeClassB的接口。

票数 1
EN

Stack Overflow用户

发布于 2016-11-30 17:06:43

时间太长,不能发表评论:

单元测试A的范围内,B的实现应该无关紧要。使用模拟/存根/任何东西来测试A的不同分支是很好的。

如果B的实现在某种程度上发生了变化,那么这与A的实现无关(在理想的场景中,但您的示例非常抽象)。如果B的实现在很大程度上发生了很大变化,以至于A正在查看B的不同成员,那么是的,您可能会对A的单元测试产生影响。如果B实现了A依赖于更改的成员,那么这与B的模拟版本无关。

然而,It 将对B的单元测试产生影响。

如果你有什么具体的东西,我可以详细说明,但现在它基本上只是一个抽象问题的抽象答案。

代码语言:javascript
复制
def functionA(objectB):
    return objectB.data < 10

def testFunctionA():
      objectB = classB()
      objectB.addData(19)      #Is this a problem or should I stub objectB?

      assert(functionA(objectB) is False)

这是蟒吗?我不知道python,但我猜functionA在objectB.data lt 10时返回true,否则返回false。

考虑到所有这些,functionA仍然只返回基于objectB成员的truefalseobjectB.data如何获取其数据与单元测试functionA的范围无关,因此objectB.data可以而且应该(在可能的情况下)被嘲弄/存根,以获得真正的单元测试。集成测试是另一回事(您应该使用真正的实现,但是您的问题是针对单元测试的)

票数 0
EN

Stack Overflow用户

发布于 2016-11-30 21:02:20

在测试中有一个规则:mock all units other than the tested one。当您调用tested单元中使用的单元时,模拟的目的是提供一些正确的输出值。您应该显式地提供一些您知道是正确的示例,这样tested单元就不会因为它所使用的单元的某些故障而失败。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40893779

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档