有没有办法检查组件是对象、数组还是字符串? 这将类似于 chai 的 'should.be.a' 例如:validationResult.SSN[0].should.be.a('string')。
不,没有。 您可以在此处找到所有可用匹配器的列表: https :
你也可以使用普通的 JavaScript 或者像lodash
这样的辅助库:
test('name', () => {
// array
expect(Array.isArray(['value'])).toBe(true);
// string
expect(typeof 'value').toBe('string');
// object
expect({value: 'value'}).toBeTruthy();
expect(typeof {value: 'value'}).toBe('object');
})
次要问题 - 这对承诺结果没有帮助。
expect(somePromise).resolves.toBe(...)
此时没有办法检查类型。 如果您不在乎内容是什么,而只关心它是一个字符串。 我希望expects.stringContaining("")
能够解决问题,但这也行不通。
@abritinthebay我正是这种情况,这是谷歌的第一个结果,也许应该重新打开?
当然,应该多考虑一下。 我的解决方法是添加到链中,以便执行typeof
部分。 例如:
expect(somePromise.then(data => typeof data)).resolves.toBe("object");
它有效,但并不完全干净。
@thymikee检查事物类型是一个足够常见的用例(通用),对于缺少它们的测试框架来说,实际上没有任何借口。 你的替代方案是不可接受的,因为我们失去了我们正在测试的所有上下文。
这个expect(Array.isArray(['value'])).toBe(false);
失败了
expect(received).toBe(expected)
Expected value to be (using ===):
false
Received:
true.
所以我们要么得到可怕的断言消息,要么我们必须扩展 Jest 来支持这些类型的检查。 对于 Jest 的维护者来说,与每个使用这些功能的人都需要自己实现它们相比,这样做一次不是更有意义吗?
然后使用expect.extend
创建您自己的匹配器并将其发布为 npm 模块。 如果它流行起来,我们最终可能会将它合并到 Jest 核心中 ;)
一个简单的 toBeType 扩展,适合那些想要它的人
expect.extend({
toBeType(received, argument) {
const initialType = typeof received;
const type = initialType === "object" ? Array.isArray(received) ? "array" : initialType : initialType;
return type === argument ? {
message: () => `expected ${received} to be type ${argument}`,
pass: true
} : {
message: () => `expected ${received} to be type ${argument}`,
pass: false
};
}
});
describe("testing extended expect", () => {
it("tests normal types correctly", () => {
expect("").toBeType("string");
expect({}).toBeType("object");
expect(1).toBeType("number");
});
it("tests array types correctly", () => {
expect([]).toBeType("array");
});
it("works with promises", () => {
expect(Promise.resolve([])).resolves.toBeType("array");
});
});
实施起来非常简单。 真的应该在核心tbh。
注意 - 如果您将该扩展放在安装文件中,那么您希望将它放在setupTestFrameworkScriptFile
不是setupFiles
(因为扩展仅在前者中可用)
谢谢@abritinthebay
因此,如果人们需要,我将其封装在一个 npm 模块中:
describe("assertion framework", ()=> {
it("should check primitive types", () => {
expect(expect.toBeA).toBeA("function")
})
})
失败:expect(...).toBeA 不是函数类型错误:expect(...).toBeA 不是函数
https://github.com/jest-community/jest-extended拥有您可能想要的所有类型匹配器(我认为)。
我一直在我的测试中使用toBeInstanceOf
:
expect($wrapper.vm.countries).toBeInstanceOf(Array);
然后使用 expect.extend 创建您自己的匹配器并作为 npm 模块发布。 如果它流行起来,我们最终可能会将它合并到 Jest 核心中 ;)
是的,并且可能会在您编写自己的 Jest 框架时编写它。
这个可能是你在 GitHub 上得到的最糟糕的答案中的佼佼者。
所以@abritinthebay完全符合@thymikee 的要求(这远远超过标准的拉取请求)。
既然那个勇敢的灵魂完成了所有的工作,我们其他人什么时候才能最终获得这个匹配器(无需安装另一个库)? 维护人员是否仍在推动这不属于 Jest 的想法,或者这只是从他们的视线中消失了?
我们对使其成为核心的内容非常严格,通常不会添加糖匹配器。 Jest 核心是一个相当大的架构,我们添加的每个匹配器都会增加维护成本
一个人的糖是另一个人的(或者在这种情况下,至少是其他七个人的)真正有用和合乎逻辑的特性,属于核心库。
显然,作为维护者,您的投票胜过我们所有人的投票,您有各种各样的担忧,我们没有,所以我完全尊重这一点。 但我只是想请您看看为什么这里的每个人都认为此功能属于核心库(如此强烈以至于一个人跳过了多个圈子为您编写代码)。 这里有一个需求,如果你忽略它 Jest核心库用户(老实说,他们中的 90% 甚至永远不会听说 jest-extended)将会失败。
.to.be.an.instanceOf
不会是多少用户认为检查类型,因此对于这些用户,即使您将其视为糖,您也实际上拒绝了他们在没有额外库的情况下在 Jest 中检查类型的能力。
是的,我听到了。 明确地说,“糖”是指旨在使事情更易于阅读或表达的语法。 糖,根据定义,是已经存在的特征的变体
在这种情况下,我们有:
// Supported
expect(typeof foo).toBe('string');
// Proposed Sugar
expect(foo).toBeType('string');
所以并不是我们不支持检查类型。 我们的确是。 我们支持第一种选择。 此选项使用核心toBe
匹配器,我们花了很多时间修复其中的错误并调整消息,以便用户获得良好的体验
Jest-extended 中有近 60 个匹配器,其中许多是纯糖。 对于这些匹配器中的任何一个,您可能会发现至少有 7 个其他人发现它们非常有用,因此如果这是我们用于添加到核心的启发式方法,我们可能会将所有时间都花在维护匹配器上
公平地说 - 大多数匹配器在某种程度上都是“糖”。 我的意思是toBeGreaterThanOrEqual
只是expect(foo >= bar).toBe(true);
糖
匹配器实际上是_几乎所有_布尔语句周围的糖;)
(我说这不是为了挖掘,只是为了指出它是......一条非常模糊的线)
正如 abritinthebay 所建议的,这并不是真正关于糖,而是关于“必要”和“不必要”(对于核心库)糖。 在这个线程中有很多人说“嘿,能够检查所有类型应该是测试库的核心”(即,这是必要的)。
听我们说或不听,作为维护者,您还有很多其他问题。 但我不认为正确的回应是说“你的糖本质上是不必要的糖”(这是我试图解释你,而不是试图把话放在你嘴里)当它不是固有的:它是 100% 你的电话是否 Jest可以检查所有类型或不开箱即用。
怎么样,是不是很难:P?
expect(Array.isArray(['your', 'array'])).toBe(true);
expect(typeof something === "object").toBe(true);
// - or -
expect(something instanceof Object).toBe(true);
expect(typeof something === "string").toBe(true);
@nahumzs虽然它有效,但问题是在您的测试输出失败时,它会说“预期假为真”,这不是很有帮助;)
我认为这是要走的路:)
describe('type check', () => {
test('should be type string', () => {
expect(typeof '').toBe('string')
})
test('should be type number', () => {
expect(typeof 10).toBe('number')
})
test('should be type boolean', () => {
expect(typeof true).toBe('boolean')
})
test('should be type undefined', () => {
expect(typeof undefined).toBe('undefined')
})
test('should be type object', () => {
expect(typeof { foo: 'bar' }).toBe('object')
})
test('should be type function', () => {
expect(typeof function() {}).toBe('function')
})
test('should be type null', () => {
expect(typeof null).toBe('object')
})
})
我重构了@abritinthebay 提供的实现。 对我来说似乎有点舒服。
```javascript
期望.扩展({
/ ** @param { } 收到
* @param {string|string[]} 参数
* @return {{pass:boolean,message:(function():string)}}
*/
toBeType(收到,arg){
const isCorrectType = arg => {
const receivedType = typeof 收到;
const checkForSingle = arg => {
const type = receivedType === 'object'
? Array.isArray(received)
? 'array'
: receivedType
: receivedType;
return type === arg;
};
const checkForArr = arg => {
const reducer = (prev, curr) => prev || isCorrectType(curr).isCorrect;
return arg.reduce(reducer, false);
};
return {
receivedType,
isCorrect: Array.isArray(arg)
? checkForArr(arg)
: checkForSingle(arg)
};
};
const {isCorrect, receivedType} = isCorrectType(arg);
return {
pass: isCorrect,
message: () => {
const toBe = Array.isArray(arg)
? arg.join(`' or '`)
: arg;
return `Expected '${received}' of '${receivedType}' type to be of '${toBe}' type(s)`;
}
};
}
});
你应该看看我的模块(上面链接)。 它的作用远不止于此。 但如果这对你有用:使用它!
我认为这是要走的路:)
describe('type check', () => { test('should be type string', () => { expect(typeof '').toBe('string') }) test('should be type number', () => { expect(typeof 10).toBe('number') }) test('should be type boolean', () => { expect(typeof true).toBe('boolean') }) test('should be type undefined', () => { expect(typeof undefined).toBe('undefined') }) test('should be type object', () => { expect(typeof { foo: 'bar' }).toBe('object') }) test('should be type function', () => { expect(typeof function() {}).toBe('function') }) test('should be type null', () => { expect(typeof null).toBe('object') }) })
它就像一种魅力,并且在未来更具可读性和可维护性。
我认为这是要走的路:)
describe('type check', () => { test('should be type string', () => { expect(typeof '').toBe('string') }) test('should be type number', () => { expect(typeof 10).toBe('number') }) test('should be type boolean', () => { expect(typeof true).toBe('boolean') }) test('should be type undefined', () => { expect(typeof undefined).toBe('undefined') }) test('should be type object', () => { expect(typeof { foo: 'bar' }).toBe('object') }) test('should be type function', () => { expect(typeof function() {}).toBe('function') }) test('should be type null', () => { expect(typeof null).toBe('object') }) })
test('should be type object', () => {
expect(typeof { foo: 'bar' }).toBe('object')
// passes
expect(typeof ['foo', 'bar']).toBe('object')
// passes
expect(typeof null).toBe('object')
})
😞
感谢您的解决方案@abritinthebay
另一种解决方案:
expect('example').toEqual(expect.any(String));
expect(123).toEqual(expect.any(String));
第二个会失败:
Expected: Any<String>
Received: 123
最有用的评论
一个简单的 toBeType 扩展,适合那些想要它的人
实施起来非常简单。 真的应该在核心tbh。
注意 - 如果您将该扩展放在安装文件中,那么您希望将它放在
setupTestFrameworkScriptFile
不是setupFiles
(因为扩展仅在前者中可用)