Question

This is Rails 4.0 App with angular-rails gem and jasmine gem. I also use angularjs-rails-resource.

I have simple controller:

app.controller('new', function ($scope, Appointment, flash) {

$scope.appointment = new Appointment();
$scope.attachments = [];
$scope.appointment.agendas_attributes = [];

$scope.createAppointment = function(){

    $scope.appointment.attachments = $scope.attachments;

    $scope.appointment.create().then(function(data){
      flash(data.message);
    }, function(error){
      flash('error', error.data.message);
      $scope.appointment.$errors = error.data.errors;
    });

};

And on the unit test in Jasmine i want to isolate dependencies with jasmine.createSpyObj:

describe("Appointment new controller",function() {
var $scope, controller, mockAppointment, mockFlash, newCtrl;


beforeEach(function() {

    module("appointments");

    inject(function(_$rootScope_, $controller) {
      $scope = _$rootScope_.$new();

      $controller("new", {
        $scope: $scope,
        Appointment: jasmine.createSpyObj("Appointment", ["create"])
      });

    });

  });
});

but i get an error:

TypeError: object is not a function

on line:

Appointment: jasmine.createSpyObj("Appointment", ["create"])

Can anybody help ? :-)

Was it helpful?

Solution

I believe the error is being thrown on this line:

$scope.appointment = new Appointment();

Appointment is an object literal, and not a function, so essentially you're trying to do this:

var x = {create: function(){}};
var y = new x();

But what you seem to want to do is this:

var x = function(){return  {create: function(){}}};
var y = new x();

So make your mock like this:

Appointment: function() {
    return jasmine.createSpyObj("Appointment", ["create"])
}

OTHER TIPS

I see someone beat me to the answer;)

I have one suggestion that will make your describe block look cleaner The module and inject statements can be nested inside the beforeEach definition:

describe("Appointment new controller", function () {
    var $scope, controller, mockAppointment, mockFlash, newCtrl;

    beforeEach(module("appointments"));
    beforeEach(inject(function (_$rootScope_, $controller) {
        $scope = _$rootScope_.$new();
        $controller("new", {
            $scope: $scope,
            Appointment: function () {
                return jasmine.createSpyObj("Appointment", ["create"])
            }
        });
    }));
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top