2017-02-24 9 views
1

jasmine.clockの使用方法ネストされた約束の中でsetTimeout模擬? (結果:Error: jasmine.DEFAULT_TIMEOUT_INTERVAL注文が問題になる場合、ネストされた約束でジャスミンクロック(setTimeout)を使用する方法? (jasmine.DEFAULT_TIMEOUT_INTERVALエラー)

ここでは重要です。

setTimeoutの内部順序の問題が必要なネストされた約束をテストする必要があります。 私はthenprocess.nextTick(またはsetImmediate)の一種であることを知って、それは(ここではコアの問題である)現在のイベントループを超えたが、これknowledgeで問題が解決しない:)

私は内部jasmine.clock().tick()を置くことができることを知っていますネストされた約束ですが、これは意味がありません。なぜなら、私はいくつかのイベント関連のlibで適切な順序をテストしているからです。

ジャスミンでこれをテストするには?何か案は?

同じ問題に来た人のために[OK]を
it("should run setTimeout mock inside chained promises",(done)=>{ 

     jasmine.clock().install(); 

     let realOrder = []; 

     let ok1=new Promise((resolve,reject)=>{ 
      resolve("ok"); 
     }).then((ok)=>{// this is future - second level 

     let p=new Promise((resolve,reject)=>{ 
      setTimeout(()=>{ // not fired up due to 'then' method 
      realOrder.push("1"); 
      resolve("1"); 
      },100); 
     }); 
     //jasmine.clock().tick(101); //<- order is crucial here so I can't do that 
     return p; 

     }); 

     let ok2=new Promise((resolve,reject)=>{ 
      resolve("ok"); 
     }).then((ok)=>{ // second level 

     let p=new Promise((resolve,reject)=>{ 
      setTimeout(()=>{ // not fired up due to 'then' method 
      realOrder.push("2"); 
      resolve("2"); 
      },50); 
     }); 
     //jasmine.clock().tick(51); //<- order is crucial here so I can't do that 
     return p; 

     }); 

     jasmine.clock().tick(151);// we must go outside nested promise - we dont need to run tick inplace because order will change 
     Promise.all([ok1,ok2]).then((results)=>{ 
     expect(results).toEqual(["1","2"]); 
     expect(realOrder).toEqual(["2","1"]); 
     done(); 
     }); 
    }); 

答えて

0

[UPDATE]:私は約束の実行のthenレベルを反復処理する関数を作成したFN https://www.npmjs.com/package/promiseloop

でNPMパッケージを作成しました各レベルでjasmine.clock().tick()のような機能を実行するので、各レベルでsetTimeoutを実行してキャッチします。

function promiseLoop(times,iterationFn,finalFn){ 
    let current=0; 
    let p=Promise.resolve("ok"); 
    function _loop(fn){ 
    current++; 
    if(current<times){ 
     p=p.then(()=>{ 
     iterationFn(current); 
     _loop(finalFn); 
     }); 
    }else{ 
     p.then(()=>{ 
     setImmediate(()=>{ 
      finalFn(); 
     }); 
     }); 
    } 
    } 
    _loop(finalFn); 
} 

timesレベルである - 私たちはthenレベルを介して行きたいどのくらい?

iterationFnは各thenレベル

finalFn上で実行される機能であり、ここで最後のレベル後


最後の関数である質問に応じた完全な例です:

it("should run setTimeout mock inside chained promises",(done)=>{ 

     jasmine.clock().install(); 

     let realOrder = []; 

     let ok1=new Promise((resolve,reject)=>{ 
      resolve("ok"); 
     }).then((ok)=>{ // second level 

     let p=new Promise((resolve,reject)=>{ 
      setTimeout(()=>{ // not fired up due to 'then' method 
      realOrder.push("1"); 
      resolve("1"); 
      },100); 
     }); 
     //jasmine.clock().tick(101); //<- order is crucial here so I can't do that 
     return p; 

     }); 

     let ok2=new Promise((resolve,reject)=>{ 
      resolve("ok"); 
     }).then((ok)=>{ // second level 

     let p=new Promise((resolve,reject)=>{ 
      setTimeout(()=>{ // not fired up due to 'then' method 
      realOrder.push("2"); 
      resolve("2"); 
      },50); 
     }); 
     //jasmine.clock().tick(51); //<- order is crucial here so I can't do that 
     return p; 

     }); 

     function iterationTick(){ 
     jasmine.clock().tick(301); 
     // this will be executed on each promise level in our case second level 
     // that normally would not be catched by 
     // jasmine.clock().tick() because 'then' will be 
     // executed in the future and jasmine.clock().tick() is synchronous 
     // and will not see future setTimeouts 
     } 

     function finalTick(){ 
     Promise.all([ok1,ok2]).then((results)=>{ 
      expect(results).toEqual(["1","2"]); 
      expect(realOrder).toEqual(["2","1"]); 
      jasmine.clock().uninstall(); 
      done(); 
     }); 
     //jasmine.clock().tick(301); 
     } 

     promiseLoop(2,iterationTick,finalTick); 


    }); 

他の例

let testNr=0; 

new Promise((resolve,reject)=>{ 
    resolve("ok"); 
}).then(()=>{ 
    // level 1 
    testNr++; // 1 
}).then(()=>{ 
    // level 2 
    testNr++; // 3 
}); 

new Promise((resolve,reject)=>{ 
    resolve("ok"); 
}).then(()=>{ 
    // level 1 
    testNr++; // 2 
}).then(()=>{ 
    // level 2 
    testNr++; // 4 
}); 

function each(currentLevel){ 
    if(currentLevel==1){ 
    expect(testNr).toEqual(2); 
    }else if(currentLevel==2){ 
    expect(testNr).toEqual(4); 
    } 
} 
function final(){ 
    expect(testNr).toEqual(4); 
    done(); 
} 
promiseLoop(3,each,final); 
関連する問題