是否可以将 Jasmine 的 toHaveBeenCalledWith 匹配器用于正则表达式?

我回顾了 Jasmine 关于 被召唤匹配器的文档,以了解是否可以为参数传入正则表达式(如果参数应该是字符串的话)。不幸的是,这是不受支持的功能。还有一个 在 github 上公开发行请求此功能。

我深入研究了代码库,并了解了如何在 现有的匹配者中实现这一点。我认为将它作为一个单独的匹配器来实现更为合适,这样抽象就可以单独捕获。

与此同时,有什么好的解决办法吗?

47001 次浏览

After doing some digging, I've discovered that Jasmine spy objects have a calls property, which in turn has a mostRecent() function. This function also has a child property args, which returns an array of call arguments.

Thus, one may use the following sequence to perform a regexp match on call arguments, when one wants to check that the string arguments match a specific regular expression:

var mySpy = jasmine.createSpy('foo');
mySpy("bar", "baz");
expect(mySpy.calls.mostRecent().args[0]).toMatch(/bar/);
expect(mySpy.calls.mostRecent().args[1]).toMatch(/baz/);

Pretty straightforward.

Alternatively, if you are spying on a method on an object:

spyOn(obj, 'method');
obj.method('bar', 'baz');
expect(obj.method.argsForCall[0][0]).toMatch(/bar/);
expect(obj.method.argsForCall[0][1]).toMatch(/baz/);

In Jasmine 2.0 the signature changed a bit. Here it would be:

var mySpy = jasmine.createSpy('foo');
mySpy("bar", "baz");
expect(mySpy.calls.mostRecent().args[0]).toMatch(/bar/);
expect(mySpy.calls.mostRecent().args[1]).toMatch(/baz/);

And the Documentation for Jasmine 1.3 has moved.

As jammon mentioned, the Jasmine 2.0 signature has changed. If you are spying on the method of an object in Jasmine 2.0, Nick's solution should be changed to use something like -

spyOn(obj, 'method');
obj.method('bar', 'baz');
expect(obj.method.calls.mostRecent().args[0]).toMatch(/bar/);
expect(obj.method.calls.mostRecent().args[1]).toMatch(/baz/);

Sometimes it is more readable to write it this way:

spyOn(obj, 'method').and.callFake(function(arg1, arg2) {
expect(arg1).toMatch(/bar/);
expect(arg2).toMatch(/baz/);
});
obj.method('bar', 'baz');
expect(obj.method).toHaveBeenCalled();

It give more clear visibility of method arguments (instead of using array)

As of Jasmine 2.2, you can use jasmine.stringMatching:

var mySpy = jasmine.createSpy('foo');
mySpy('bar', 'baz');
expect(mySpy).toHaveBeenCalledWith(
jasmine.stringMatching(/bar/),
jasmine.stringMatching(/baz/)
);