2017-02-24 2 views
1

Wie benutze ich jasmine.clock setTimeout Mock innerhalb verschachtelter Versprechen? (Ergebnis: Error: jasmine.DEFAULT_TIMEOUT_INTERVAL)Wie verwende ich Jasmine clock (setTimeout) in verschachtelten Versprechen, wenn die Bestellung wichtig ist? (jasmine.DEFAULT_TIMEOUT_INTERVAL error)

Reihenfolge ist hier entscheidend.

Ich muss verschachtelte Versprechen testen, die SetTimeout innerhalb haben muss - Reihenfolge Angelegenheiten. Ich weiß, dass then Art von process.nextTick (oder setImmediate) und es geht über die aktuelle Ereignisschleife (die das Kernproblem hier ist), aber dies knowledge löst nicht das Problem :)

Ich weiß, dass ich nach innen setzen kann jasmine.clock().tick() geschachteltes Versprechen, aber das ist sinnlos, weil ich die richtige Reihenfolge in einigen mit Ereignissen zusammenhängenden Bibliotheken teste.

Wie testet man so etwas in Jasmin? irgendwelche Ideen?

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(); 
     }); 
    }); 

Antwort

0

Ok für diejenigen, die mit dem gleichen Problem kam:

[UPDATE]: Ich habe ein npm Paket mit dieser fn https://www.npmjs.com/package/promiseloop

ich eine Funktion erstellt, die durch then Ebenen Versprechen Ausführung laufen wird und auf jeder Ebene eine Funktion wie jasmine.clock().tick() ausführen, so dass auf jeder Ebene setTimeout ausgeführt und abgefangen wird.

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 ist eine Ebene - wie weit wir durch then Ebene gehen?

iterationFn ist Funktion, die

finalFn ist eine endgültige Funktion nach der letzten Stufe auf jeder then Ebene ausgeführt werden


hier ist ein vollständiges Beispiel nach Frage:

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); 


    }); 

anderes Beispiel

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); 
Verwandte Themen