2017-07-25 102 views
0

我有暴露发电机的实用功能:如何窥探静态发生器功能?

export class Utility { 
    // provides a generator that streams 2^n binary combinations for n variables 
    public static *binaryCombinationGenerator(numVars: number): IterableIterator<boolean[]> { 
     for (let i = 0; i < Math.pow(2, numVars); i++) { 
      const c = []; 
      //fill up c 
      yield c; 
     } 
    } 
} 

现在,我使用如下这种发电机在我的代码:

myFuncion(input){ 
    const n = numberOfVariables(input); 
    const binaryCombinations = Utility.binaryCombinationGenerator(n); 
    let combination: boolean[] = binaryCombinations.next().value; 
    while (till termination condition is met) { 
     // do something and check whether termination condition is met   
     combination = binaryCombinations.next().value; 
    } 
} 

在我的单元测试(使用茉莉花)我想在终止之前验证生成器函数被调用的次数(即生成了多少个组合)。以下是我所尝试的:

it("My spec",() => { 
    //arrange 
    const generatorSpy = spyOn(Utility, "binaryCombinationGenerator").and.callThrough(); 
    //act 
    //assert 
    expect(generatorSpy).toHaveBeenCalledTimes(16); // fails with: Expected spy binaryCombinationGenerator to have been called 16 times. It was called 1 times. 
}); 

但是,这个断言失败,因为binaryCombinationGenerator确实被调用过一次。我实际上想要窥探的是next方法IterableIterator

但是,我不知道该怎么做。请建议。

回答

0

我张贴此作为一个答案,因为这是我做了什么嘲笑生成函数返回一个茉莉间谍对象。这是基于@0mpurdy's answer

为了模拟生成器函数,我们实际上需要调用一个伪函数,它将为生成器函数的每个调用next()提供不同的(并且限制,如果适用)值。

这可以通过以下简单地实现:

//arrange 
const streamSpy= jasmine.createSpyObj("myGenerator", ["next", "counter"]); 
streamSpy.counter = 0; 
const values = [{ value: here }, { value: goes }, { value: your }, { value: limited }, 
       { value: values }]; // devise something else if it is an infinite stream 

// call fake function each time for next 
streamSpy.next.and.callFake(() => { 
    if (streamSpy.counter < values.length) { 
     streamSpy.counter++; 
     return values[streamSpy.counter - 1]; 
    } 
    return { value: undefined }; // EOS 
}); 
spyOn(Utility, "myGenerator").and.returnValue(streamSpy); 

... 
//assert 
expect(streamSpy.next).toHaveBeenCalledTimes(2); 
1

你可以从Utility.binaryCombinationGenerator方法

let binaryCombinationsSpy = jasmine.createSpyObject('binaryCombinations', ['next']); 
binaryCombinationsSpy.next.and.returnValues(value1, value2); 
spyOn(Utility, "binaryCombinationGenerator").and.returnValue(binaryCombinationsSpy); 

expect(binaryCombinationsSpy.next).toHaveBeenCalledTimes(2); 
+0

+1谢谢您的回答。但是,为了模拟发生器,我需要更多东西。我已经发布了我的解决方案作为答案。如果你有兴趣,你可以看看。 –