Angular 6单元测试静态模拟响应

时间:2019-02-28 14:40:30

标签: angular unit-testing

我正在测试一个调用服务方法的Angular组件。在该组件内,我在继续之前修改了响应的某些字段,例如:

ngOnInit() {
    this.myService.myMethod(requestData).subscribe(response => {
      response.list.forEach(item => {
        item.someField = someValue;
      })
    });
    ...
}

为了进行测试,我创建了一个模拟响应,如下所示:

const mockServiceResponse = {
    list: [],
    ...
}

const myServiceSpy = jasmine.createSpyObj('MyService',['myMethod']);
myServiceSpy .myMethod.and.returnValue( of(mockServiceResponse ) );

问题是;我有几个测试用例,每个测试用例都调用ngOnInit。在修改服务响应字段时,每次运行 mockServiceResponse 对象都会被修改,第二个测试用例将获得响应的修改版本。这对于componenet来说不是问题,因为每次调用该方法时我实际上都会得到一个新的响应,但是对于测试它会导致我的测试用例失败。关于如何为每个测试用例获取新版本的 mockServiceResponse 的任何想法?

2 个答案:

答案 0 :(得分:0)

您可以使用useThisValue = JSON.parse(JSON.stringify(mockValue))从模拟值中复制并使用完整的对象。

答案 1 :(得分:0)

您可以利用beforeEach来设置每个测试的测试条件。您可以嵌套describe并添加更多beforeEach调用来控制事物执行的频率。

此示例将一次设置您的测试模块。每次规范中的测试,它将创建一个“ mockServiceResponse”并模拟一次myMethod

describe('MyComponent', () => {
    const myServiceSpy = jasmine.createSpyObj('MyService',['myMethod'])    

    beforeEach(() => {
        /* 
         * Set up angular testing module
         * Declare your component(s)
         * Provide your spy as the implementation for the service you want to mock
         * This will run once for the entire spec
         */ 
    });

    describe('some more specific description', () => {
       //This will run before each test
       beforeEach(() => {
            let mockServiceResponse = {
                list: [],
                ...
            };
            myServiceSpy .myMethod.and.returnValue( of(mockServiceResponse ) );
        });

        it('does something', () => {
            //run your test
        });

        it('does another thing', () => {
            //run your test
        });
    });
});