我应该测试模块是否具有某些属性?

mis*_*ala 7 javascript testing

我在过去的两个月里一直在编写测试(用JavaScript).并且,我习惯检查模块是否具有某些属性.

例如:

// test/foo.js
const Foo = require('../lib/foo');
const Expect = require('chai').expect;

describe('Foo API', () => {
    it('should have #do and #dont properties', () => {
        Expect(foo).to.have.property('do')
            .and.to.be.a('function');

        Expect(foo).to.have.property('dont')
            .and.to.be.a('function');
        });
     });
});
Run Code Online (Sandbox Code Playgroud)

而且,我一直在想我是否正在做正确的事情.只是想知道一些事情:

  1. 这种模式是"正确的"吗?

    • 它被广泛使用?
    • 还有其他方法吗?
  2. 如果它不"正确"?

    • 为什么?
  3. 它甚至有意义吗?

    • 我的意思是,这是不必要的还是多余的?

Eri*_*ott 17

不要测试类型.测试特定属性值是否符合预期值.

因此,编写一个调用foo并期望特定结果的测试代替"is foo a function".

如果foo不是函数,则会生成错误并且测试将失败(这很好).如果foo是一个函数,你将对该函数的行为进行适当的测试.


Mat*_*zer 7

有一个范例,称之为鸭打字,说(维基百科):

在duck typing中,程序员只关心确保对象在给定的上下文中按照它们的要求行事,而不是确保它们属于特定的类.例如,在非鸭类型的语言中,可以创建一个函数,该函数要求传递给它的对象是Duck类型,或者来自Duck类型,以确保该函数可以使用对象的walk和嘎嘎方法.在duck-typed语言中,该函数将获取任何类型的对象,并简单地调用其walk和quack方法,如果未定义它们则会产生运行时错误.鸭子打字实践不是正式指定类型,而是依赖文档,清晰的代码和测试来确保正确使用.

我将集中讨论以上文本的以下部分:

在duck-typed语言中,该函数将采用任何类型的对象并简单地调用其walk和quack方法,如果未定义它们则会产生运行时错误

和...

[...]鸭子打字实践依赖于文档,清晰的代码和测试,以确保正确使用.

也就是说,因为JavaScript是一种动态类型的语言非常适合鸭子打字.

换句话说,你应该避免这些测试.如果模块具有缺少的属性或者存在不需要的类型,则会出现运行时错误,这足以说明调用者没有履行隐式契约以使其与给定模块一起正常工作.

在运行时期间由代码行为定义的整个合同可以通过良好的文档页面强制执行.