سؤال

New to unit testing in general and Jasmine in particular.

I've set a variable in a beforeEach() callback, but it doesn't seem to work on the second test. It's supposed to fire initialization stuff in advance of every test within its context, right? I'm sure my spyOn() call is to blame, but I don't know how to fix it.

Comments explain the passes and fails:

describe("Test suite for my library", function () {
  var html,
      body,
      play,
...

  // custom matcher...
  beforeEach(function () {
    this.addMatchers({
      toBeInstanceOf : function (constructr) {
        return this.actual instanceof constructr;
      });
    });
  });

  describe("Within the Button object", function () {

    beforeEach(function () {
      play = new Button("play", false);
    });

    describe("play", function () {

      // This test passes, as expected...
      it("should be an instance of the Button object", function () {
        expect(play).toBeInstanceOf(Button);
      });

    });

    describe("play.name", function () {

      // This test failed with the message
      // "Expected spy Button to have been called
      //  with [ 'play', false ] but it was never called."
      it("should be the first argument passed to the Button constructor", function () {
        spyOn(window, "Button");
        play = new Button("play", false); // ...until I added this line. Now it passes.
        expect(window.Button).toHaveBeenCalledWith("play", false);
      });

      // This test passes, even if the one above fails.
      it("should be 'play'", function () {
        expect(play.name).toBe("play");
      });

    });

  });
});

The documentation explains the usage, but not the context, of spyOn(), so I can't tell if I've created a bug or if I'm unknowingly taking advantage of a feature.

I can post the constructor if anyone thinks it makes any difference in the diagnosis, but I can assure you it's dead simple.

I'm sure it's a straightforward fix using some basic unit testing concept I'm having to learn the hard way. Thanks in advance.

P.S. I realize what I'm testing for in that failing spec isn't what I've described. I'm working my way through the API guide, looking for a way to get to the arguments array within a function call, so I can do a specific test on arguments[0]. Hints are appreciated, but not necessary. I'll figure it out.

هل كانت مفيدة؟

المحلول

Short answer: No, Before each and spies are not incompatible

You must Spy before you call if you want the spy to know about the call. You can use spyOn(object, 'function').andCallThrough() if you do not wish to interfere with its default behavior.

Long answer: The way faking/mocking/stubbing/spying frameworks often work is by replacing the method you are calling with a method that the mocking framework can control. Any calls to that function before it is replaced with the spy cannot be observed. This is a good thing, though mildly inconvenient,

نصائح أخرى

Its cause you spy on window.Button after you have called. Im not totally sure what spy does, but after all it displaced the function you spy on with another function where it can check the function was called and whats arguments was passed. When you create your Button before your start your test, the original window.button function called. Then you replaces the function with the spy and test that the spy was called, so your test must fail.

Seems either create your Button in the test itself or create your spy before you call new Button in your beforeEach function.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top