Why do I have to call spyOn in a beforeEach()?

jasmine, javascript, unit-testing

Solution

That is simply because Jasmine runs the Specs in a different closure. The `describe` and `it` calls only register callbacks that are added to a queue and then executed by Jasmine later. And Jasmine always cleans up the spies ...

But you can also add the `spyOn` to the `it` callback.

Problem

I have a simple test suite that has one `it` function inside of it. I want to see if a certain function is called within the function I'm calling, so I have something like this: ``` describe("doStuff", function () { var foo = new Foo(); spyOn(foo, "doOtherStuff"); foo.doStuff(true); it("should do stuff and other stuff", function() { expect(foo.stuffDone).toBe(true); expect(foo.doOtherStuff).toHaveBeenCalled(); }); }); ``` However, this gives me the error: `Expected a spy, but got Function.` After looking around some, I saw all examples had the `spyOn` in a `beforeEach`. So, I changed my test to: ``` describe("doStuff", function () { var foo = new Foo(); beforeEach(function() { spyOn(foo, "doOtherStuff"); foo.doStuff(true); }); it("should do stuff and other stuff", function() { expect(foo.stuffDone).toBe(true); expect(foo.doOtherStuff).toHaveBeenCalled(); }); }); ``` And this works. I'm pretty new to jasmine, so I may just be missing something obvious, but I just want to know why it has to be in a `beforeEach` for the `spyOn` to work. It's easy enough to just use the `beforeEach`, but I want to understand better what is going on. Thanks.

Original source