如何测试使用 Jasmine 调用异步函数的函数



如何测试这个函数:

var self = this;
self.someVariable = "initial value";
self.test = function() {
self.functionWhichReturnsPromise().then(function() {
self.someVariable = "new value";
});
}

我有如下测试用例,我知道这是错误的,因为在解决承诺之前,断言语句将由茉莉执行:

it("should test the function test", function (done) {
var abc = new ABC();
abc.test();
expect(abc.someVariable).toBe('new value');
});

请注意,我不想使用 setTimeout(( 或任何睡眠方法。

两件事,你需要你的test函数来returnPromise,你需要使用箭头函数或.bind对父函数的回调(否则this.someVariable中的this将引用回调函数(:

this.test = function() {
return this.functionWhichReturnsPromise().then(() => {
this.someVariable = "new value";
});
}

this.test = function() {
return this.functionWhichReturnsPromise().then(function() {
this.someVariable = "new value";
}.bind(this));
}

然后在测试中,您可以执行以下操作:

it("should test the function test", function (done) {
var abc = new ABC();
abc.test().then(function() {
expect(abc.someVariable).toBe('new value');
done();
});
});

您可以监视返回承诺的函数。

describe('when test method', function() {
beforeEach(function() {
this.promiseResult = Math.random();
spyOn(ABC.prototype, 'functionWhichReturnsPromise')
.and.returnValue(Promise.resolve(this.promiseResult));
})
it('then should change someVariable with the result of functionWhichReturnsPromise', function() {
var abc = new ABC();
abc.test();
expect(abc.someVariable).toBe(this.promiseResult);
});
});

无需等待 promise,在这个单元测试中,你对 functionWhichReturnsPromise 的实际工作方式不感兴趣,你只想看到调用 functionWhichReturnsPromise 的结果会更新一些变量值。

玩得开心,好运

现在asyncawait在茉莉花中可用。 您可以使用它们来测试您的异步函数天气它是一个承诺或可观察的天气。

it("should test the function test", async (done) => {
var abc = new ABC();
abc.test();
expect( await abc.someVariable).toBe('new value');  // await will wait until abc.someVariable resolved or rejected
});

我一直在我的 angular 4 应用程序测试中使用asyncawait,它应该适合您。

我写了两个示例来展示如何在测试函数中等待承诺。
JavaScript: https://codepen.io/zhangyanwei/pen/rNNXKaV

function trackPromise() {
const P = Promise;
Promise = function() {
const p = new P(...arguments);
Object.assign(this, p);
Promise.recent = p;
};
Object.assign(Promise, P);
}

打字稿:https://codepen.io/zhangyanwei/pen/ZEEgNNB

// Mixin interface, you could put it into *.d.ts file.
interface PromiseConstructor {
recent: Promise<unknown>;
}
function trackPromise() {
// Only overwrite the constructor
const P = Promise;
Promise = function<T>(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void): Promise<T> {
const p = new P(executor);
Promise.recent = p;
return p;
} as unknown as PromiseConstructor;
}

最新更新