代码之家  ›  专栏  ›  技术社区  ›  Paul Geisler

如何监视一个函数,该函数内部有一个Promise,但不返回结果,而是处理响应本身?

  •  1
  • Paul Geisler  · 技术社区  · 6 年前

    // Game.js
    
    export default {
        mine: null,
    
        handle: function(me) {
            console.log("   FOOOOO " + me)
        },
    
        setSource: function() {
            this.mine.getSource().then((response) => {
              const {source} = response
              this.handle(source)
            })
        }
    }
    

    在这里我试着监视:

    // GameSpec.js
    
    import Game from '../../lib/jasmine_examples/Game'
    
    Game.mine = {}
    
    describe("Game", function() {
      it("should set source and handle it", function() {
    
        Game.mine.getSource = () => {
          return new Promise((resolve)=>{
            resolve( {
              source : 'BAAAAR'
            })
          })
        }
    
        spyOn(Game, 'handle').and.callThrough()
    
        Game.setSource()
    
        expect(Game.handle).toHaveBeenCalled()
      });
    });
    

    在输出中可以看到函数“handle”被调用:

    Started
    F   FOOOOO BAAAAR
    
    
    Failures:
    1) Game should set source and handle it
      Message:
        Expected spy handle to have been called.
      Stack:
        Error: Expected spy handle to have been called.
            at <Jasmine>
            at UserContext.<anonymous> (/Users/silverbook/Sites/zTest/jasmine/spec/jasmine_examples/PlayerSpec.js:20:29)
            at <Jasmine>
    
    1 spec, 1 failure
    

    jasmine 说没打电话来。

    如果我把被嘲笑的 Promise 考试通过了,但我需要去那里。在另一个测试中,我将返回Promise中的错误并让它从另一个函数处理。

    所以 打破了测试但为什么?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Brian Adams    6 年前

    测试同步执行,并且 expect 在回调排队之前失败 this.mine.getSource().then()

    为了 Jasmine >=2.7和 async 函数支持您可以将测试函数转换为 异步 函数并添加 await Promise.resolve();

    对于您的测试,它将如下所示:

    import Game from '../../lib/jasmine_examples/Game'
    
    Game.mine = {}
    
    describe("Game", function() {
      it("should set source and handle it", async () => {
    
        Game.mine.getSource = () => {
          return new Promise((resolve)=>{
            resolve( {
              source : 'BAAAAR'
            })
          })
        }
        spyOn(Game, 'handle').and.callThrough();
    
        Game.setSource();
    
        await Promise.resolve(); // let the event loop cycle
    
        expect(Game.handle).toHaveBeenCalled();
      });
    });
    

    茉莉 可以使用的版本 done() 这样地:

    import Game from '../../lib/jasmine_examples/Game'
    
    Game.mine = {}
    
    describe("Game", function() {
      it("should set source and handle it", (done) => {
    
        Game.mine.getSource = () => {
          return new Promise((resolve)=>{
            resolve( {
              source : 'BAAAAR'
            })
          })
        }
        spyOn(Game, 'handle').and.callThrough();
    
        Game.setSource();
    
        Promise.resolve().then(() => {
          expect(Game.handle).toHaveBeenCalled();
          done();
        });
    
      });
    });
    
        2
  •  1
  •   Boris Yakubchik    5 年前

    你可以在里面进行测试 fakeAsync tick() expect()

    服务:

    getFirebaseDoc() {   
      this.db.firestore.doc('some-doc').get()
        .then(this.getFirebaseDocThen)
        .catch(this.getFirebaseDocCatch);
    }
    

    it('should call getFirebaseDocThen', fakeAsync(() => {          // note `fakeAsync`
        spyOn(service, 'getFirebaseDocThen');
        spyOn(service.db.firestore, 'doc').and.returnValue({
          get: (): any => {
            return new Promise((resolve: any, reject: any): any => {
              return resolve({ exists: true });
            });
          },
        });
        service.getFirebaseDoc();
        tick();                                                     // note `tick()`
        expect(service.getFirebaseDocThen).toHaveBeenCalled();
    }));