Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/460.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Jasmine单元测试:我应该测试逻辑还是实际的模拟数据?_Javascript_Angular_Unit Testing_Jasmine_Karma Jasmine - Fatal编程技术网

Javascript Jasmine单元测试:我应该测试逻辑还是实际的模拟数据?

Javascript Jasmine单元测试:我应该测试逻辑还是实际的模拟数据?,javascript,angular,unit-testing,jasmine,karma-jasmine,Javascript,Angular,Unit Testing,Jasmine,Karma Jasmine,在执行单元测试时,最好测试我期望硬编码到测试中的文字结果(expect(x).toBe(17)),还是测试逻辑而不是我正在使用的特定模拟数据(expect(x).toBe(mockedData.value)) 第一种方法似乎更安全,因为我确信测试实际上是在测试我期望的文字结果,但是第二种方法更灵活,因为它允许我测试逻辑,而不必担心模拟数据(我以后也可以更改模拟数据,而不必重写测试本身) 这两种方法的优点/缺点是什么?在这些情况下,最佳做法是什么 下面是一个快速示例: // MockedData

在执行单元测试时,最好测试我期望硬编码到测试中的文字结果(
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
    }) 
});

非常感谢!!:)

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

最危险的方法是使用
expect(instance.plusOne()).toBe(17)
,因为如果有人将您的逻辑更改为
,则返回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()

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