I love the partial object matching that jasmine.objectContaining provides:
mySpy({ foo: 'bar', bar: 'baz' }); expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({ foo: 'bar' }));
Is there a jasmine equivalent for strings? something along the lines of:
mySpy('fooBar', 'barBaz'); expect(mySpy).toHaveBeenCalledWith(jasmine.stringContaining('foo'), jasmine.any(String));
I’d like to look at a specific argument without resorting to assertions off mySpy.calls:
mySpy('fooBar', 'barBaz'); expect(mySpy.calls.argsFor(0)[0]).toContain('foo');
Advertisement
Answer
There isn’t anything of this sort in Jasmine. But you can leverage the ability of creating a custom matcher in Jasmine for this.
Here’s a small working example:
Your Factories
angular.module('CustomMatchers', []).factory('AnotherService', function(){ return{ mySpy: function(a, b){ } } }); angular.module('CustomMatchers').factory('MyService', function(AnotherService){ return{ myFunction: function(a, b){ AnotherService.mySpy(a, b); } } });
Your test case with a custom matcher
describe('Service: MyService', function() { beforeEach(module('CustomMatchers')); describe('service: MyService', function() { beforeEach(inject(function(_MyService_, _AnotherService_) { MyService = _MyService_; AnotherService = _AnotherService_; spyOn(AnotherService, 'mySpy'); jasmine.addMatchers({ toContain: function() { return { compare: function(actual, expected){ var result = { pass: actual.includes(expected) }; if(result.pass) { result.message = "Success: Expected first arguments '" + actual + "' to contain '"+ expected +"'."; } else { result.message = "Failour: Expected first arguments '" + actual + "' to contain '"+ expected +"'."; } return result; } } } }); })); it('expect AnotherService.mySpy toHaveBeenCalled', function() { MyService.myFunction('fooBar', 'barBaz'); //This should pass expect(AnotherService.mySpy.calls.argsFor(0)[0]).toContain('foo'); //This should fail expect(AnotherService.mySpy.calls.argsFor(0)[0]).toContain('helloWorld'); }); }); });
Hope this helps!