jasmine: toHaveBeenCalledWith() crashes test environment when matching large objects

Problem: toHaveBeenCalledWith() matcher with large objects

Outcome: crashes the entire environment (PhantomJS) or runs recursively (Chrome).

Workaround create a custom equality tester (jasmine.addCustomEqualityTester) before “toHaveBeenCalledWith()” is called. This leads to the EqualityTester failing rather than the environment crashing 😃

Setup:

  • Angular2
  • Jasmine 2.5.2

Example:

Some sort of injectable service

@Injectable()
class EventService {
    broadcast(name: string, ...args: any[]) {
		//do something
	}
}

A big/complex object to match like an Angular component

class Angular2Component {

	someFunction() {
		injectedEventService.broadcast("myEventName", this);	//this being the component itself
	}

}

Now the Test

describe(() => {

    it("myTest", inject([EventService], (eventService: EventService) => {
	
		spyOn(eventService, "broadcast");
		//createComponent
		component.someFunction();
		
		expect(eventService.broadcast).toHaveBeenCalled(); // true

		// When the second argument isn't passed, the equlity matcher crashes the 
                // environment
		expect(eventService.broadcast).toHaveBeenCalledWith("myEventName")
	
                // Also crashes the environment when the argument amount is correct but one value is
                // not correct
                expect(eventService.broadcast).toHaveBeenCalledWith("someOtherEventName", jasmine.any(Angular2Component));

	}));

})

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 15 (5 by maintainers)

Commits related to this issue

Most upvoted comments

If the error only occurs when the matcher fails, it is probably that the PrettyPrinter is crashing while trying to print out the object. The PrettyPrinter should skip over circular object graphs, and print out a message. You should also be able to set your jasmine.MAX_PRETTY_PRINT_DEPTH to something lower than the default of 40 since it looks like that object is quite wide but not necessarily very deep.

The Jasmine PrettyPrinter will also look for a custom toString (or jasmineToString if you want it for specs only) that will pre-empt any recursing.

Hope this helps. Thanks for using Jasmine!