有没有办法如何使用Jasmine和Typescript监视构造函数?
有问题的建议解决方案Spying on a constructor using Jasmine不起作用,因为TypeScript does not expose global declarations on window
。
这是我的用例:
// higher-order function returns validation function with max length
const maxLengthValidator = maxLength => value => value.length > maxLength;
class Book {
// will be a different function instance each time the Book object is
// created causing the following test to fail
nameValidator = maxLengthValidator(42);
name = null;
constructor (name) { this.name = name; }
}
class Library {
persons = [];
storeBook (book) { this.persons.push(book); }
createBook (name) { this.storeBook(new Book(name)); }
}
测试失败:
it('createBook passes new book with provided name to storeBook', () => {
const lib = new Library();
spyOn(lib, 'storeBook');
lib.createBook('Start with Why');
expect(lib.storeBook).toHaveBeenCalledWith(new Book('Start with Why'));
// Result: Expected spy storeBook to have been called with
// [ Book({ name: 'Start with Why', nameValidator: Function }) ]
// but actual calls were
// [ Book({ name: 'Start with Why', nameValidator: Function }) ]
});
在测试中,我并不关心构造函数的作用。我只需要验证是否已使用正确的参数调用它。这甚至听起来像是模拟的正确用例。
答案 0 :(得分:0)
可以使用两个函数的toString
值对其进行比较。您可以添加自定义的相等性测试器,也可以添加新的匹配器。
function replacer(k, v) {
if (typeof v === 'function') {
v = v.toString();
}
return v;
}
function stringifyEquality(a, b) {
try {
return JSON.stringify(a, replacer) === JSON.stringify(b, replacer) ? true : undefined;
} catch (e) {
return undefined
}
}
beforeAll(() => {
jasmine.addCustomEqualityTester(stringifyEquality);
});
it('createBook passes new book with provided name to storeBook', () => {
const lib = new Library();
spyOn(lib, 'storeBook');
lib.createBook('Start with Why');
expect(lib.storeBook.calls.mostRecent().args).toEqual([new Book('Start with Why')]);
});
function replacer(k, v) {
if (typeof v === 'function') {
v = v.toString();
}
return v;
}
beforeEach(() => {
jasmine.addMatchers({
toBeJsonEqual: function(expected){
var one = JSON.stringify(this.actual, replacer).replace(/(\\t|\\n)/g,''),
two = JSON.stringify(expected, replacer).replace(/(\\t|\\n)/g,'');
return one === two;
}
});
});
expect(obj).toBeJsonEqual(obj2);