I have a pretty closely related old code that I want to cover with tests. It is sometimes important to ensure that one wearing method is called before the other. A simplified example:
function PageManager(page) { this.page = page; } PageManager.prototype.openSettings = function(){ this.page.open(); this.page.setTitle("Settings"); };
In the test, I can verify that both open() and setTitle() :
describe("PageManager.openSettings()", function() { beforeEach(function() { this.page = jasmine.createSpyObj("MockPage", ["open", "setTitle"]); this.manager = new PageManager(this.page); this.manager.openSettings(); }); it("opens page", function() { expect(this.page.open).toHaveBeenCalledWith(); }); it("sets page title to 'Settings'", function() { expect(this.page.setTitle).toHaveBeenCalledWith("Settings"); }); });
But setTitle() will only work after the first call to open() . I would like to verify that the first page.open() is called and then setTitle() . I would like to write something like this:
it("opens page before setting title", function() { expect(this.page.open).toHaveBeenCalledBefore(this.page.setTitle); });
But Jasmine does not seem to have such functionality.
I can hack something like this:
beforeEach(function() { this.page = jasmine.createSpyObj("MockPage", ["open", "setTitle"]); this.manager = new PageManager(this.page); // track the order of methods called this.calls = []; this.page.open.and.callFake(function() { this.calls.push("open"); }.bind(this)); this.page.setTitle.and.callFake(function() { this.calls.push("setTitle"); }.bind(this)); this.manager.openSettings(); }); it("opens page before setting title", function() { expect(this.calls).toEqual(["open", "setTitle"]); });
This works, but I wonder if there is an easier way to achieve this. Or some good way to generalize this, so I wonβt need to duplicate this code in other tests.
PS. Of course, the right way is to reorganize the code to eliminate this temporary connection. This may not always be possible, for example, when interacting with third-party libraries. In any case ... I would like to first examine the existing code with the help of tests, changing it as little as possible before delving into further refactoring.