我在angular2项目上使用jasmine并且在编写自定义匹配器时遇到了一些麻烦。我希望能够比较两个相对复杂的对象。我发现this article声称解决了这个问题,但它只会导致打字稿错误,说明它没有识别茉莉花的Matchers
对象上的新方法。相关代码是:
declare module jasmine {
interface Matchers {
toBeNumeric(): void;
}
}
Another article给出了一个类似但略有不同的解决方案,它会产生同样的错误。
declare namespace jasmine {
interface Matchers {
toHaveText(expected: string): boolean;
}
}
我试过这个
let m: jasmine.Matchers = expect(someSpy.someMethod).toHaveBeenCalled();
并收到此错误:
键入' jasmine.Matchers'不能分配给#jasmine.Matchers'。 存在两种具有此名称的不同类型,但它们是不相关的。
这似乎表明declare namespace jasmine
语句正在创建一个新的jasmine
命名空间,而不是扩展现有的命名空间。
那么如何创建我自己的打字稿,打字稿会很满意?
答案 0 :(得分:4)
Daf的答案主要适合我,我只是注意到他的示例代码和他命名文件的方式存在问题。我也遇到了另一个无关的问题。因此,一个新的答案。
示例自定义匹配器: - https://github.com/vespertilian/wallaby-angular-node-yarn-workspaces/tree/master/api/src/test-helpers 此处的示例规格: - https://github.com/vespertilian/wallaby-angular-node-yarn-workspaces/blob/master/api/src/hello/hello.spec.ts
匹配器 - custom-matchers.ts
import MatchersUtil = jasmine.MatchersUtil;
import CustomMatcherFactories = jasmine.CustomMatcherFactories;
import CustomEqualityTester = jasmine.CustomEqualityTester;
import CustomMatcher = jasmine.CustomMatcher;
import CustomMatcherResult = jasmine.CustomMatcherResult;
export const SomeCustomMatchers: CustomMatcherFactories = {
toReallyEqual: function (util: MatchersUtil, customEqualityTester: CustomEqualityTester[]): CustomMatcher {
return {
compare: function (actual: any, expected: any): CustomMatcherResult {
if(actual === expected) {
return {
pass: true,
message: `Actual equals expected`
}
} else {
return {
pass: false,
message: `Actual does not equal expected`
}
}
}
}
}
};
接口文件 - matcher-types.d.ts - 不能与匹配文件同名
declare namespace jasmine {
interface Matchers<T> {
toReallyEqual(expected: any, expectationFailOutput?: any): boolean;
}
}
自定义匹配器测试
describe('Hello', () => {
beforeEach(() => {
jasmine.addMatchers(SomeCustomMatchers)
});
it('should allow custom matchers', () => {
expect('foo').toReallyEqual('foo');
expect('bar').not.toReallyEqual('test');
})
});
答案 1 :(得分:2)
基本上,你的第二个例子(“声明命名空间”)是可行的方式,当然,还有其他地方的匹配器的逻辑。
欢迎你看一下https://github.com/fluffynuts/polymer-ts-scratch/tree/5eb799f7c8d144dd8239ab2d2bcc72821327cb24/src/specs/test-utils/jasmine-matchers我写过一些茉莉花匹配器和打字机的地方 - 虽然从技术上来说我用Javascript写了实际的匹配器并命名了逻辑文件.ts安抚我的构建过程。
您将需要安装@types/jasmine
- 并保持最新状态。
请记住@types/jasmine
的不同版本可能会破坏事物;具体来说,上面链接的提交是Jasmine类型引入Matchers
类型的类型参数(即Matchers<T>
),它打破了我所有的.d.ts文件。
答案 2 :(得分:0)
如果您使用的是ES模块,则需要将名称空间声明包装在declare global
块中。
以下是更新的示例,其中两个自定义匹配器已合并到相同的定义中:
declare global {
namespace jasmine {
interface Matchers {
toBeNumeric(): void;
toHaveText(expected: string): boolean;
}
}
}
也可以将声明分开(甚至分散在多个文件中):
// File 1 declares this matcher
declare global {
namespace jasmine {
interface Matchers {
toBeNumeric(): void;
}
}
}
// File 2 declares this matcher
declare global {
namespace jasmine {
interface Matchers {
toHaveText(expected: string): boolean;
}
}
}
// File 3: use the custom matchers
it(function(){
expect(3).toBeNumeric();
expect(result).toHaveText('custom matcher');
});
注意:在这些摘要中,namespace
和module
关键字是等效的,但不建议使用module
,而首选namespace
(以避免与ES模块或CommonJS模块混淆)