【问题标题】:Unit Testing Assertion when using Mocks使用 Mocks 时的单元测试断言
【发布时间】:2015-12-14 10:18:29
【问题描述】:

我正在使用模拟编写单元测试,并想征求意见。我的具体示例是模拟“window”对象,但是在其他情况下可能会出现问题。

请注意,我正在对单元测试进行逆向工程,TDD 是我们在这里采用的一种新风格。

我正在测试的模块将返回 URL 的哈希部分并从中获取参数。例如,如果哈希值为:

#param=value&param2=value2

然后模块会返回一个像这样的对象:

{
  param: 'value',
  param2: 'value2'
}

我写的第一个单元测试是返回没有哈希的哈希值。方法如下:

getCurrentHash: function() {
    return window.location.hash.slice(1);
},

我已经模拟了窗口对象以将window.location.hash 设置为等于#param=value&param2=value2

我希望 getCurrentHash 在此特定情况下返回 param=value&param2=value2

window对象是hash模块的依赖,我在运行测试时切换了路径使用mocked版本。

问题

是否应该像这样针对模拟数据进行单元测试:

tdd.test('getCurrentHash', function () {
    var currentHash = hash.getCurrentHash();            
    currentHash.should.equal('param=value&param2=value2');
});

或者单元测试应该测试返回值的格式,像这样:

tdd.test('getCurrentHash', function () {
    var currentHash = hash.getCurrentHash();            
    currentHash.should.not.contain('#');
    currentHash.should.be.a('string');
    currentHash.should.have.length.above(0);
});

这个问题的出现是因为模拟可能会改变。例如,如果我们决定在模拟中添加空格,我们最终会将其修改为param=value&param2=value2+withspace。这将使测试失败,我需要将测试更改为:

tdd.test('getCurrentHash', function () {
    var currentHash = hash.getCurrentHash();            
    currentHash.should.equal('param=value&param2=value2+withspace');
});

但是,对于更通用的第二个测试,我不需要更改单元测试。

我已经阅读了一些文章,包括下面列出的文章,但我找不到任何关于断言应该断言什么的详细推理

【问题讨论】:

    标签: javascript unit-testing mocking


    【解决方案1】:

    您想测试您希望从正在测试的事物中看到的行为。您的行为是(基于实现)返回窗口位置哈希值减去“#”字符。因此,您应该测试以下内容:

    • 如果不存在任何值,则不返回任何内容(但不返回错误(除非您明确希望这样做))
    • 存在值时返回预期值

    恕我直言,您的第二个测试几乎没有价值,因为我可以将实现更改为此,测试仍然可以通过。

    getCurrentHash: function() {
        return "bob";
    }
    

    这使得测试毫无用处。您的测试用于验证系统的行为。因此,编写测试来设置快乐路径条件、失败案例和边缘案例,并让他们验证事情的行为是否符合您的预期。

    【讨论】:

    • 这对于鼓励在工作中进行更多对话很有用。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多