typemoq
typemoq copied to clipboard
detecting multiple calls when only one is present
This seems to completely be a bug and I don't see this happening anywhere else... I have an isolated test as shown below:
fdescribe('getSelectedRangeAsHelper', () =>
{
const address = 'ABC123:DEF456';
beforeAll(() =>
{
spyOnProperty(service, 'ctx').and.returnValue(mContext.object);
mocks.forEach(m => m.reset());
mContext.setup(x => x.workbook).returns(() => mWorkbook.object);
mContext.setup(x => x.sync()).returns(() => Promise.resolve(undefined));
mWorkbook.setup(x => x.getSelectedRange()).returns(() => mRange.object);
mRange.setup(x => x.address).returns(() => address);
});
it('should return a range helper for the address of the selected range', async () =>
{
const helper = await service.getSelectedRangeAsHelper();
// TODO not sure why this one is broke and saying it is run 3 times... --- TWW
expect(() => mWorkbook.verify(x => x.getSelectedRange(), Times.once())).not.toThrow();
expect(() => mRange.verify(x => x.load({ address: true }), Times.once())).not.toThrow();
expect(() => mContext.verify(x => x.sync(), Times.once())).not.toThrow();
expect(helper).toEqual(jasmine.any(Helpers.RangeHelper));
expect(helper.address()).toEqual(address);
});
});
Some background: I'm mocking objects from the ExcelApi which is not available at runtime when the karma-jasmine test runs, so the dynamic testing is required. Also, this is karma-jasmine run for an Angular project.
The function being tested is on a class:
async getSelectedRangeAsHelper():Promise<RangeHelper>
{
const ctx = this.ctx;
const selected = ctx.workbook.getSelectedRange();
selected.load({ address: true });
await ctx.sync();
return new RangeHelper(selected.address);
}
Any ideas what might be happening? Other mocking/testing methods show that it is indeed being called once, so I sense that I could be misunderstanding or misusing typemoq or that this is a bug.
... and I'm having it happen again on this test...
The function on the class:
async sheetExists(name:string):Promise<boolean>
{
const ctx = this.ctx;
const ws = ctx.workbook.worksheets.getItemOrNullObject(name);
ws.load('isNullObject');
await ctx.sync();
return !ws.isNullObject;
}
The test that is failing (the second spec says that it is being invoked 7 times when it is clearly being invoked once per test)...
fdescribe('sheetExists', () =>
{
beforeEach(() =>
{
spyOnProperty(service, 'ctx').and.returnValue(mContext.object);
mocks.forEach(m => m.reset());
mContext.setup(x => x.workbook).returns(() => mWorkbook.object);
mContext.setup(x => x.sync()).returns(() => Promise.resolve(undefined));
mWorkbook.setup(x => x.worksheets).returns(() => mWorksheets.object);
mWorksheets.setup(x => x.getItemOrNullObject('existing sheet')).returns(() => mNullObject.object);
mWorksheets.setup(x => x.getItemOrNullObject('non existing sheet')).returns(() => mNullObject.object);
});
it('should getItemOrNullObject and return false if it is a null object', async () =>
{
mNullObject.setup(x => x.isNullObject).returns(() => false);
const exists = await service.sheetExists('existing sheet');
expect(exists).toBe(true);
expect(() => mWorksheets.verify(x => x.getItemOrNullObject('existing sheet'),Times.once())).not.toThrow();
expect(() => mNullObject.verify(x => x.load('isNullObject'), Times.once())).not.toThrow();
expect(() => mContext.verify(x => x.sync(), Times.once())).not.toThrow();
});
it('should getItemOrNullObject and return true if it is not a null object', async () =>
{
mNullObject.setup(x => x.isNullObject).returns(() => true);
const exists = await service.sheetExists('non existing sheet');
expect(exists).toBe(false);
expect(() => mWorksheets.verify(x => x.getItemOrNullObject('non existing sheet'), Times.once())).not.toThrow();
expect(() => mNullObject.verify(x => x.load('isNullObject'), Times.once())).not.toThrow();
expect(() => mContext.verify(x => x.sync(), Times.once())).not.toThrow();
});
});
Unless I'm doing something wrong in my syntax, then this is making typemoq completely unusable.
I am also running into this issue. I think it is related to verify on a function named "load". I think the number that it returns instead of one is returning the count of other invocations. It was saying that I was invoking load five times which correlates to the number of await calls I called in my class + the one actual call to "load".