【问题标题】:Jasmine Unit Test: should I test the logic or the actual mocked data?Jasmine 单元测试:我应该测试逻辑还是实际的模拟数据?
【发布时间】:2018-02-21 00:13:03
【问题描述】:

在执行单元测试时,最好测试我期望将其硬编码到测试中的文字结果 (expect(x).toBe(17)),还是测试逻辑而不是我正在使用的特定模拟数据更好 ( expect(x).toBe(mockedData.value))

第一种方法似乎更安全,因为我确信测试实际上是在测试我期望的文字结果,但是第二种方法更灵活,因为它允许我测试逻辑而不是担心模拟数据(我也可以稍后更改,而无需重写测试本身)

这两种方法的优点/缺点是什么?在这些情况下,最佳做法是什么?

下面是一个简单的例子:

// MockedData is a very long array of complex objects 
// each of them has a property 'value' of type number 
import mockedData from 'data.mock';

class ClassToTest {
    private data;
    constructor(data) {
        this.data = data;
    }
    plusOne(): number {
        return this.data.value + 1;
    } 
}

describe('test', () => {
    let instance: ClassToTest;
    beforeEach(() => {
        instance = new ClassToTest(mockedData[0]);
    })
    it('plusOne() should return the property "value" plus one', () => {
        // Should I write this...
        expect(instance.plusOne()).toBe(mockedData[0] + 1);
        // ...or this?
        expect(instance.plusOne()).toBe(17); // Because I know that mockedData[0].value is 16
    }) 
});

非常感谢!! :)

【问题讨论】:

  • 这是一个很好的问题,不幸的是,它不适合 SO,因为没有正确的答案,无论哪种方式都有论据。在这种情况下,方法是 plusOne,看到断言是 something +1 是有意义的。但是,在较少编造的情况下,使用硬编码数字通常更容易理解正在测试的内容(即使更改模拟数据时它会使测试更加脆弱。
  • TBH 你做了一个 input 17 = ouput 17 这不是测试。如果你这样做 input true = ouput 17 那么这是一个测试。尝试对组件进行测试,因为如果您提供正确的输入,您的服务应该始终给出预期的结果。如果不是,您的输入错误或您的后端流程错误。
  • IMO using mockedData 对这个测试用例更具描述性,如果是: 16.plusOne 应该返回 17 那么我同意使用文字。您的断言应与规范描述保持一致
  • 您可以通过多种方式测试组件,所有方式都是针对特定条件设计的。它不像你只会使用一种方式而不是另一种方式。顺便说一句,您会将预期结果存储在硬编码文件中。这与技术无关。
  • 顺便说一句,你的两个测试都失败了;)你需要调用方法

标签: javascript angular unit-testing jasmine karma-jasmine


【解决方案1】:

在您的测试中,您想测试您的单元,在您的情况下,这是您的 plusOne() 函数内部的逻辑。所以你只想知道函数内部是否发生了变化。

最危险的路径是使用expect(instance.plusOne()).toBe(17);,因为如果有人将您的逻辑更改为return this.data.value + 2;,只有当问题出在函数逻辑或mockedData中时,您将永远无法从测试中发现。

较不危险的方法是使用expect(instance.plusOne()).toBe(mockedData[0] + 1);,因为这会告诉你函数中的逻辑是否发生了变化。仍然不是最佳的,因为您依赖外部模拟来运行您不需要的测试。为什么要依赖外部模拟数据来测试您的单元?

在这里测试您的单元逻辑的最佳方法是执行以下操作:

describe('test', () => {
    let instance: ClassToTest;
    const mockedValue = 1;
    beforeEach(() => {
        instance = new ClassToTest(mockedValue);
    })
    it('plusOne() should return the property "value" plus one', () => {
        expect(instance.plusOne()).toBe(mockedValue + 1);
    }) 
});

然后,你可以为你的服务实现单独的测试,这里你只测试plusOne()里面的逻辑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-19
    • 1970-01-01
    • 2018-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多