2017-04-26 99 views
0

我正在测试pub子类的发布方法。我在beforeEach函数内创建一个回调函数并订阅这个类。在它的方法中,我发布了事件并试图测试回调被调用,这基本上是该类的工作原理。我有测试工作,它通过,但问题是我不得不使用setTimeout得到这个工作。我相信这可能不是正确的做法。无功能间谍功能

describe('publish',() => { 
    let testpublish; 
    let callback; 

    beforeEach(() => { 
    callback = function(data) { return data + 10; } 
    testpublish = { 
     'id': 'testpublish1', 
     'event': 'testpublish', 
     'callback': callback 
    }; 
    subject.subscribe(testpublish); 
    }); 

    it('should call the subscription function',() => { 
    subject.publish('testpublish', 9); 
    setTimeout(() => { 
     expect(callback).toEqual(19); 
    }); 
    }); 
}); 

我最初想窥探回调只是为了看它是否被调用,但茉莉的文件说,我必须把我的方法在一个对象:

spyOn(OBJ,方法名)→ {间谍}

任何意见,以更好的方式来做到这一点,将不胜感激。谢谢。

PubSub类如果有用?

@Injectable() 
export class Pubsub { 
    private events: any = {}; 

    public subscribe(config: any) { 
    let event = config['event']; 
    this.events[event] = this.events[event] || []; 

    if (this.events[event].length < 1) { 
     this.events[event].push(config); 
    } else { 
     for (let i = 0; i < this.events[event].length; i++) { 
     if (this.events[event][i].id !== config.id) { 
      this.events[event].push(config); 
     } 
     } 
    } 
    } 

    public unsubscribe(obj: Object) { 
    let event = obj['event']; 
    let id = obj['id']; 

    if (this.events[event]) { 
     this.events[event] = this.events[event].filter((eventObj) => { 
     return eventObj.id !== id; 
     }); 
    } 

    if (this.events[event].length === 0) { 
     delete this.events[event]; 
    } 
    } 

    public publish(event: string, data: any) { 
    if (this.events[event]) { 
     this.events[event].forEach(function(obj) { 
     obj.callback(data); 
     }); 
    } 
    } 

    public getEvents() { 
    return this.events; 
    } 
} 

回答

0

现有功能无法窥探,因为间谍是一个新的功能,并以原有功能的引用在它被调用的地方已被使用。

考虑到callback功能是在测试本身定义的,而不是应用程序里面,它应该被定义为在首位间谍:

callback = jasmine.createSpy(); 

它甚至没有做一些事情,因为它的返回值不会为测试增加值。

而且它像

const arg = {}; 
subject.publish('testpublish', arg); 

expect(callback.calls.count()).toBe(1); 
expect(callback.calls.first().args[0]).toBe(arg); 

publish测试是同步的,以及所述类的其余部分。没有必要setTimeout,这是有害的。当done参数没有被指定用于测试时,它被认为是同步的,并且setTimeout在此测试中使断言被忽略。

it('should pass',() => { 
    setTimeout(() => { 
     expect(1).toBe(2); 
    }); 
    }); 

,永远传承。只有当套件没有其他测试时,这将触发SPEC HAS NO EXPECTATIONS警告。

+0

谢谢。我赞赏详细的解释,并指出我在代码中犯的其他错误。 – Aaron

+0

不客气。 – estus

0

jasmine.createSpy('spy')将会工作。

describe('publish',() => { 
    let testpublish; 
    let callback; 
    let subject = new Pubsub(); 

    beforeEach(() => { 

    callback = function (data) { 
     return data + 10; 
    } 
    testpublish = { 
     'id': 'testpublish1', 
     'event': 'testpublish', 
     'callback': jasmine.createSpy('spy') 
    }; 
    subject.subscribe(testpublish); 
    }); 

    it('should call the subscription function',() => { 
    subject.publish('testpublish', 9); 
    expect(testpublish.callback).toHaveBeenCalledWith(9); 
    }); 
}); 
+0

谢谢你的回应。我对第二个答复给出了答案,因为它不仅回答了我的问题,还澄清了我在代码中犯的其他错误。我感谢你的回应。 – Aaron

+0

当然。它是。 howevere“expect(callback.calls.first()。args [0])。toBe(arg);”比“expect(testpublish.callback).toHaveBeenCalledWith(9);”更难读。 –

+0

是的,我同意你的意见。我所指的部分是当他在存根中加入值时指出缺乏对测试的价值。另外我觉得详细的解释可能会帮助其他可能犯同样错误的人。我很难把答案给予他,因为你确实先回答了。再次感谢你。 – Aaron