【问题标题】:unit testing and mocking then methods in promises单元测试和模拟 promise 中的 then 方法
【发布时间】:2018-04-02 04:07:34
【问题描述】:

如果有一段逻辑要通过各种顺序承诺进行单元测试,那么如何在then(() => {}) 函数中实际断言逻辑?通过与下面类似的设置,我遇到了第一个测试将通过但第二个测试没有通过的问题。我很好奇为什么实现中的匿名 then 块永远不会到达。

//Implementation
class FiddleService {
    constructor(dependencies = {}) {
        const { someService = new SomeService() } = dependencies;
        this.someService = someService;
    }

    doSomething(params) {
        this.someService.asyncOperation1(params).then((result) => {
            ...
            //never gets called by spy in test
            return this.someService.asyncOperation2(result.firstName);
        }).then((result) => {
            return this.someService.asyncOperation3(result.age);
        });
    }
}
//test
describe("FiddleService", () => {
    let someService;
    beforeAll(() => {
        someService = new SomeService();
        spyOn(someService.asyncOperation1).and
          .returnValue(new Promise(() => {firstName: "Jan"});
        spyOn(someService.asyncOperation2).and
          .returnValue(new Promise(() => {age: 50});
        spyOn(someService.asyncOperation3);
    });

    it("calls asyncOperation1", () => {
        let fiddleService = new FiddleService();
        fiddleService.doSomething({});
        expect(someService.asyncOperation1).toHaveBeenCalled();
    });

    it("calls asyncOperation2", () => {
        let fiddleService = new FiddleService();
        fiddleService.doSomething({});
        expect(someService.asyncOperation2).toHaveBeenCalled();
    });
});

【问题讨论】:

  • 这两个new Promise(() => ...) 表达式返回永远不会被解决的承诺。 Promise.resolve(...),在两个地方,似乎更合适。

标签: node.js unit-testing promise jasmine


【解决方案1】:

正如@roamer-1888 所说,该解决方案与在测试中调用承诺和调用完成有关。

//test
describe("FiddleService", () => {
    let someService;
    beforeAll(() => {
        someService = new SomeService();
        spyOn(someService.asyncOperation1).and
          .returnValue(new Promise(() => {firstName: "Jan"});
        spyOn(someService.asyncOperation2).and
          .returnValue(new Promise(() => {age: 50});
        spyOn(someService.asyncOperation3);
    });

    it("calls asyncOperation1", () => {
        let fiddleService = new FiddleService();
        fiddleService.doSomething({});
        expect(someService.asyncOperation1).toHaveBeenCalled();
    });

    it("calls asyncOperation2", (done) => {
        let fiddleService = new FiddleService();
        fiddleService.doSomething({}).then(_ => {
            expect(someService.asyncOperation2).toHaveBeenCalled();
            done();
        });
    });
});

【讨论】:

  • 我不确定我帮了多少忙,但是嘿,很高兴得到提及,谢谢。
【解决方案2】:

茉莉花不是我技能的主要部分,所以暂时提供。

我仍然认为您在两个地方需要 Promise.resolve() 而不是 new Promise(),并且认为您可以利用 Jasmine 在单个测试中处理多个 expect() 的能力,而不会丢失信息。

//test
describe("FiddleService", () => {
    let someService;
    beforeAll(() => {
        someService = new SomeService();
        spyOn(someService.asyncOperation1).and.returnValue(Promise.resolve({firstName: "Jan"}));
        spyOn(someService.asyncOperation2).and.returnValue(Promise.resolve({age: 50}));
        spyOn(someService.asyncOperation3);
    });

    it("should make three sequential async calls", (done) => {
        let fiddleService = new FiddleService();
        fiddleService.doSomething({}).then(_ => {
            expect(someService.asyncOperation1).toHaveBeenCalled();
            expect(someService.asyncOperation2).toHaveBeenCalled();
            expect(someService.asyncOperation3).toHaveBeenCalled();
            done();
        });
    });
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-16
    • 1970-01-01
    • 2015-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多