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

Javascript 如何使用Jasmine测试调用异步函数的函数,javascript,jquery,promise,jasmine,Javascript,Jquery,Promise,Jasmine,如何测试此功能: var self = this; self.someVariable = "initial value"; self.test = function() { self.functionWhichReturnsPromise().then(function() { self.someVariable = "new value"; }); } this.test = function() { return this.functionWhichRetur

如何测试此功能:

var self = this;
self.someVariable = "initial value";
self.test = function() {
   self.functionWhichReturnsPromise().then(function() {
     self.someVariable = "new value";
   });
}
this.test = function() {
   return this.functionWhichReturnsPromise().then(() => {
     this.someVariable = "new value";
   });
}
我有下面这样的测试用例,我知道它是错误的,因为在解决承诺之前,断言语句将由jasmine执行:

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

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

两件事,您需要使用
test
函数来
返回承诺,并且需要使用arrow函数或
。将回调绑定到父函数(否则
this.someVariable
中的
this
将引用回调函数):

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

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

现在,jasmine中提供了
async
await
。您可以使用它们来测试您的异步功能,无论它是承诺还是可观察到的

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应用程序测试中使用了
async
wait
,它应该适合您。

您只需监视返回承诺的函数即可

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);
  });
});
无需等待承诺,在这个单元测试中,您对函数whichreturnspromise的实际工作方式不感兴趣,您只想看到调用函数whichreturnspromise的结果将更新一些变量值


祝你玩得开心和好运

我已经编写了两个示例来演示如何在测试函数中等待承诺。
JavaScript

类型脚本

//Mixin接口,您可以将其放入*.d.ts文件中。
接口承诺构造函数{
近期:承诺;
}
函数trackPromise(){
//仅覆盖构造函数
const P=承诺;
承诺=功能(执行者:(解析:(值?:T |承诺)=>无效,拒绝:(原因?:任何)=>无效)=>无效):承诺{
常数p=新的p(执行者);
Promise.recent=p;
返回p;
}与承诺人一样未知;
}

我已经编辑了这个问题,所以剩下的唯一一件事就是从
test
函数返回承诺。假设我不能编辑
test
函数来返回承诺,那么还有没有办法测试变量
someVariable
?如果你不能返回承诺,那么就没有办法用输出一个
setTimeout
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);
  });
});
function trackPromise() {
  const P = Promise;
  Promise = function() {
    const p = new P(...arguments);
    Object.assign(this, p);
    Promise.recent = p;
  };
  Object.assign(Promise, P);
}
// 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;
}