Reputation: 34632
I am trying to stub the following:
on('complete', function(data){ });
I only want to call the callback if the first parameter is 'complete'.
The function I am testing also contains:
on('error', function(data){ });
So I can't just do yield cause that will fire both the complete and the error callback.
If I wouldn't use sinon I would fake it by writing the following.
var on = function(event, callback){
if (event === 'complete'){
callback('foobar');
};
};
Upvotes: 15
Views: 11007
Reputation: 114
getNewPairsEventHandler()
getNewPairsEventHandler()
in this case is a class method which can be easily stubbed or spyed with sinon if needed.service.ts:
private getNewPairsEventHandler() {
return async(event: pairEvent) => {
//...
}
}
// Listen for new pairs
public async getNewPairs() {
const newPairsEvent = await this.uniswapPairCreatedFactory.events.PairCreated()
newPairsEvent.on('data', this.getNewPairsEventHandler())
newPairsEvent.on('error', (e: Error) => {
throw new BaseError('Error fetching new pairs', e)
})
}
test.ts:
describe('[SUCCESS]', () => {
let uniswapPairCreatedFactoryStub: sinon.SinonStub
let eventHandlerFn: any
let newPairsEvent: EventEmitter
let uniswapPairCreatedFactoryStub: sinon.SinonStub
const expectedEventArgs = {
returnValues: { token0, token1, pair }
}
beforeEach(() => {
eventHandlerFn = (<any>ethCoinManager.contract).getNewPairsEventHandler()
newPairsEvent = new EventEmitter()
uniswapPairCreatedFactoryStub = sinon.stub(
ethCoinManager.contract.uniswapPairCreatedFactory.events, 'PairCreated'
).resolves(newPairsEvent)
})
afterEach(() => {
uniswapPairCreatedFactoryStub.restore()
})
it.only('should listen for new pair events and save them to the database', async() => {
await getNewPairs()
await new Promise(resolve => {
newPairsEvent.once('data', () => {
resolve(true)
})
newPairsEvent.emit('data', expectedEventArgs)
})
expect(anythinghere)
})
})
Stub Service Event with Event Emitter
service.ts
// Listen for new pairs
public async getNewPairs() {
const newPairsEvent = await this.uniswapPairCreatedFactory.events.PairCreated()
newPairsEvent.on('data', this.getNewPairsEventHandler())
newPairsEvent.on('error', (e: Error) => {
throw new BaseError('Error fetching new pairs', e)
})
}
test.js
describe('[newPairsEvent]', () => {
let newPairsEvent: EventEmitter
let uniswapPairCreatedFactoryStub: sinon.SinonStub
const errorMessage = 'Test error'
beforeEach(() => {
newPairsEvent = new EventEmitter()
uniswapPairCreatedFactoryStub = sinon.stub(
ethCoinManager.contract.uniswapPairCreatedFactory.events, 'PairCreated'
).resolves(newPairsEvent)
})
afterEach(() => {
uniswapPairCreatedFactoryStub.restore()
})
it('should throw an error if there is an error fetching new pairs', async() => {
await ethCoinManager.contract.getNewPairs()
try {
newPairsEvent.emit('error', new Error(errorMessage))
expect(true).toBe(false)
} catch (e: any) {
expect(e.name).toBe('BaseError')
expect(e.message).toBe('Error fetching new pairs')
expect(e.httpStatus).toBe(500)
expect(e.e.message).toBe(errorMessage)
}
})
})
Upvotes: 0
Reputation: 926
You can narrow the circumstances under which a yield
occurs by combining it with a withArgs
like so...
on.withArgs('complete').yields(valueToPassToCompleteCallback);
on.withArgs('error').yields(valueToPassToErrorCallback);
Upvotes: 9
Reputation: 110892
Maybe you can use a spyCall:
var spy = sinon.spy(window, 'on');
on('error', function(data){ });
on('complete', function(data){ });
for(var i=0; i < spy.callCount; i++){
var call = spy.getCall(i);
if(call.args[0] === 'complete') call.args[1]('foobar');
}
Upvotes: 0