Javascript 测试结果呈指数增长的场景

Javascript 测试结果呈指数增长的场景,javascript,unit-testing,testing,Javascript,Unit Testing,Testing,真正吸引我使用TDD的一件事是,在实现的同时明确地开发了规范 我正在寻求实现一个接受配置对象的构造函数 function MyConstructor(conf) {} conf目前被指定有两个键:a和b,其中a是一个RegExp,b是一个函数,作为我的TDD规范说明目标的一部分,我正在编写测试来说明这个对象: 如果a不是RegExp或b不是函数,我希望MyConstructor抛出错误 MyConstructor如果配置中缺少a或b,将抛出错误 现在,我知道我可以将此行为封装到其他构造函数

真正吸引我使用TDD的一件事是,在实现的同时明确地开发了规范

我正在寻求实现一个接受配置对象的构造函数

function MyConstructor(conf) {}
conf
目前被指定有两个键:
a
b
,其中
a
是一个
RegExp
b
是一个
函数
,作为我的TDD规范说明目标的一部分,我正在编写测试来说明这个对象:

  • 如果
    a
    不是
    RegExp
    b
    不是
    函数,我希望
    MyConstructor
    抛出
    错误
    
  • MyConstructor
    如果配置中缺少
    a
    b
    ,将抛出
    错误
    
现在,我知道我可以将此行为封装到其他构造函数中,比如创建“配置”对象的
配置
构造函数。但是我现在看到的情况是,不管这个行为最终会发生在哪里,这个行为必须被封装在某个地方,以便通过TDD来详细说明这个规范

问题是:在我看来,随着
conf
对象上键的数量增加,测试的数量也呈指数增长!这尤其是由于上面的第二个项目


例如,假设我有4个键:
a
b
c
d
,我需要确保如果缺少任何键,就会抛出一个错误。这似乎要求我编写大量相同的、平庸的测试,涵盖所有可能的(组合!)缺少的键。听起来不对!然而,我想不出一个明确或归纳测试所有场景的好方法。有什么想法吗?

没有类定义或接口的对象很难测试。如果对象是鸭子,则需要使用DuckType进行检查

您还可能想知道完全测试某些函数有多有用。您可以测试边界,但永远无法测试所有值

如果函数如下所示:

function sum(a, b) {
    if (a === 42) {
        throw new Error("All glory to the hypnotoad");
    }
    return a + b;
}

您希望如何找到此错误?

我建议您使用来强制执行这些类型。本质上,您要做的是按照您的期望使用键传入的对象,如果
a
的行为不像正则表达式,或者您不能像函数一样调用
b
,那么让JS运行时抱怨

所以,我在想,但在问题中没有提到。这是你的观点,那么,我应该如何详细说明规格?JS通过TDD进行规范很糟糕?使用该语言最干净的方法是duck键入,不要强调该语言没有的功能。JS缺少接口,因此TDD有限。冷静点。你可以随时引入自己的打字系统,但要牺牲一些开销。哈哈哈,我在努力,我在努力。只是有点沮丧。是的,duck类型很好,但是我必须非常依赖于运行时行为的集成测试,对吗?嗯,模拟也不会那么容易,因为没有可以模拟的规范。天哪,太糟糕了。是的,我想是这样的,现在你们证实了这种恐惧。通过TDD的规格说明到此为止。我想我应该冷静下来!简而言之,测试黄金路径,并合理记录。相信你的对象的用户会做正确的事情,并帮助他们知道这是什么。仍然要通过TDD进行规范,只是不要指望它能解决人们错误地使用你的对象的问题!TDD对于设计和规范对象的工作方式非常有用。它可以教你很多关于代码的知识。记住,信任你的用户是可以的。谢谢@Totalymike。我会的。我会在右前臂纹上“测试黄金之路”。我对这个问题有点困惑。规范将声明,如果ctor缺少任意数量的任意键中的任意一个,它将失败。您不必测试所有的组合(而且您也可以通过编程方式进行测试),只需确保是否缺少任何必需的键即可。听起来像是简单的对象验证,存在预构建的解决方案。@DaveNewton,因此在我有限的单元测试经验中,我从未见过使用循环或嵌套循环编写的单元测试,并在组合上迭代。你是说,鉴于测试必须(a)快速(b)简单,这样做是正确的吗?(不确定最后一个,但这是我的印象)。如何以有意义的方式以编程方式创建置换比手工编写的相同测试慢?如果你真的需要测试所有的排列,它们也会随着时间的推移变得更加正确。。。这一点我相当怀疑,如果我们只讨论确保所有必需参数都存在的需要。@DaveNewton,你完全正确,但我应该首先编写这些循环吗?我非常希望通过测试来规范我规范的每个细节,但我也不想对JavaScript做不应该对JavaScript做的事情。你认为呢?我认为以编程方式生成测试数据没有问题。我甚至以编程方式生成测试和规范,尽管不是用JavaScript。