Limitations on Spies

BrianGenisio edited this page Apr 5, 2011 · 1 revision

Jasmine has a rich Spy interface for creating test doubles. This functionality has been ported over to Jasmine-Flex with one limitation: you cannot spy on namned functions.

This is because ActionScript implements named functions differently than JavaScript. In JavaScript, you can define something like classes:

var Klass = function () {
};

Klass.prototype.method = function (arg) {
  return arg;
};

Inside your spec, you can spy on it:

it("should spy", function() {
    var obj = new Klass();
    spyOn(obj, "method");
    // rest of spec
});

Internally, the method function is wrapped and replaced. Something like this:

objToSpyOn.method = wrappedFunction;

In ActionScript, we have the concept of real classes with named functions:

public class Klass {
    public function method(arg) {
        return arg;
    }
}

The problem is that if you try to spy on it the same way, you get an exception. This is because method is no longer modifiable. Even if you get into Klass.prototype, you get no love. You get runtime errors when you try to modify named functions.

The spy mechanism DOES work, however, if you use anonymous functions like javascript:

public class Klass {
    public var method:Function = function(arg) {
        return arg;
    }
}

With that modification, you can spy on method with your instance of Klass just like in Javascript.

Unfortunately, we are now compromising our idiomatic ActionScript code for the sake of testing. If you'd prefer to bring in a mocking library, take a look at how you can integrate easily with Mockito.