测试内部调用异步方法的函数

时间:2020-02-28 18:00:49

标签: angularjs jasmine

我的功能如下:

let a;
let b;

const functionThatCallsAsync = ()=> {
    a = 1;

    asyncFn().then(() => {
        b = 2;
    }).catch(() => {
        // catch stuff
    })

}

在单元测试中:

describe('functionThatCallsAsync', () => {
    it('should set a and b', (done: () => void) => {
        spyOn(ctrl, 'asyncFn').and.returnValue(Promise.resolve());

        functionThatCallsAsync();
        setTimeout(() => {
            expect(ctrl.asyncFn).toHaveBeenCalled();
            expect(a).toEqual(1);
            expect(b).toEqual(2);
            done;
        }, 1)    
})

测试成功断言了函数的同步部分(等于1)中的内容,并且调用了asyncFn,但没有断言异步部分(b等于2)中的内容。我在这里想念什么?

注意:ctrl是定义了我要在单元测试文件中创建实例的函数的控制器。假定在定义asyncFn的地方定义了functionThatCallsAsync

谢谢!

3 个答案:

答案 0 :(得分:0)

在单元测试中,异步期望应该在调用functionThatCallsAsync函数之后进入函数,然后进入函数

ctrl.asyncFn().then(() => { expect(b).toEqual(2); });

答案 1 :(得分:0)

要在JavaScript或Angular中测试异步功能,我将async/awaitfixture.whenStable()一起使用

类似的情况

describe('functionThatCallsAsync', () => {
    it('should set a and b', async done => {
        spyOn(ctrl, 'asyncFn').and.returnValue(Promise.resolve());

        functionThatCallsAsync();
        // fixture.whenStable() ensures all promises have resolved
        await fixture.whenStable();
        expect(ctrl.asyncFn).toHaveBeenCalled();
        expect(a).toEqual(1);
        expect(b).toEqual(2);
        // Call the done function to tell the test you are done with the assertions
        done();
});

答案 2 :(得分:-1)

如果您使用async/await并按如下所示增加超时,则它应该可以工作。

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

export default class SelectDate extends Component {

    constructor() {
        super();
        this.state = {
            value: ''
        }
    }

    selectDate(e) {
        let url = window.location.href
        let date = e.target.value
        this.setState({value: date})
        axios.get(url+ '/' +date).then(response => {
            alert(response.data)
            document.getElementById('dashboard_content').innerHTML = response.data
        }).catch(error => {
            alert(error)
        })
    }

    render() {
        return (
            <div>
                <select className="custom-select custom-select-sm" onChange={this.selectDate.bind(this)} value={this.state.value}>
                    <option selected value='7'>Last Week</option>
                    <option value="1">Today</option>
                    <option value="30">Last Month</option>
                </select>
            </div>
        );
    }
}

if (document.getElementById('select-date')) {
    ReactDOM.render(<SelectDate />, document.getElementById('select-date'));
}