zealoushacker
zealoushacker

Reputation: 6906

Is it possible to use Jasmine's toHaveBeenCalledWith matcher with a regular expression?

I have reviewed Jasmine's documentation of the toHaveBeenCalledWith matcher in order to understand whether it's possible to pass in a regular expression for an argument, if that argument is expected to be a string. Unfortunately, this is unsupported functionality. There's also an issue open on github requesting this functionality.

I've dug a bit into the codebase, and I see how it might be possible to implement this inside the existing matcher. I think it would be more appropriate to implement it as a separate matcher though, so that the abstraction is captured individually.

In the meantime, what might be a good workaround?

Upvotes: 77

Views: 49665

Answers (6)

Rusty Shackleford
Rusty Shackleford

Reputation: 1141

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/)
);

Upvotes: 45

Maciej Dzikowicki
Maciej Dzikowicki

Reputation: 887

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)

Upvotes: 8

zealoushacker
zealoushacker

Reputation: 6906

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.

Upvotes: 96

Blake
Blake

Reputation: 2397

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/);

Upvotes: 7

jammon
jammon

Reputation: 3464

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.

Upvotes: 24

Nick Hingston
Nick Hingston

Reputation: 8880

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/);

Upvotes: 13

Related Questions