I'm just starting out writing tests for my AngularJS app and am doing so in Jasmine.
Here are the relevant code snippets
ClientController:
'use strict'; adminConsoleApp.controller('ClientController', function ClientController($scope, Client) { //Get list of clients $scope.clients = Client.query(function () { //preselect first client in array $scope.selected.client = $scope.clients[0]; }); //necessary for data-binding so that it is accessible in child scopes. $scope.selected = {}; //Current page $scope.currentPage = 'start.html'; //For Client nav bar $scope.clientNavItems = [ {destination: 'features.html', title: 'Features'}, ]; //Set current page $scope.setCurrent = function (title, destination) { if (destination !== '') { $scope.currentPage = destination; } }; //Return path to current page $scope.getCurrent = function () { return 'partials/clients/' + $scope.currentPage; }; //For nav bar highlighting of active page $scope.isActive = function (destination) { return $scope.currentPage === destination ? true : false; }; //Reset current page on client change $scope.clientChange = function () { $scope.currentPage = 'start.html'; }; });
ClientControllerSpec:
'use strict'; var RESPONSE = [ { "id": 10, "name": "Client Plus", "ref": "client-plus" }, { "id": 13, "name": "Client Minus", "ref": "client-minus" }, { "id": 23805, "name": "Shaun QA", "ref": "saqa" } ]; describe('ClientController', function() { var scope; beforeEach(inject(function($controller, $httpBackend, $rootScope) { scope = $rootScope; $httpBackend.whenGET('http://localhost:3001/clients').respond(RESPONSE); $controller('ClientController', {$scope: scope}); $httpBackend.flush(); })); it('should preselect first client in array', function() { //this fails. expect(scope.selected.client).toEqual(RESPONSE[0]); }); it('should set current page to start.html', function() { expect(scope.currentPage).toEqual('start.html'); }); });
The test fails:
Chrome 25.0 (Mac) ClientController should preselect first client in array FAILED Expected { id : 10, name : 'Client Plus', ref : 'client-plus' } to equal { id : 10, name : 'Client Plus', ref : 'client-plus' }. Error: Expected { id : 10, name : 'Client Plus', ref : 'client-plus' } to equal { id : 10, name : 'Client Plus', ref : 'client-plus' }. at null.<anonymous> (/Users/shaun/sandbox/zong-admin-console-app/test/unit/controllers/ClientControllerSpec.js:43:39)
Does anyone have any ideas on why this might be happening?
Also .. as I'm new to writing AngularJS tests, any comments on whether I'm setting up my test wrong or whether it can be improved will be welcome.
Update:
Including ClientService:
'use strict'; AdminConsoleApp.services.factory('Client', function ($resource) { //API is set up such that if clientId is passed in, will retrieve client by clientId, else retrieve all. return $resource('http://localhost:port/clients/:clientId', {port: ':3001', clientId: '@clientId'}, { }); });
Also, I got around the problem by comparing ids instead:
it('should preselect first client in array', function () { expect(scope.selected.client.id).toEqual(RESPONSE[0].id); });
You are trying to compare two different instances of an object which is true for regular equality ( a == b ) but not true for strict equality ( a === b). The comparator that jasmine uses is jasmine. Env. equals_() which looks for strict equality.
Jasmine is a behavior driven development framework for JavaScript that has become the most popular choice for testing AngularJS applications. Jasmine provides functions to help with structuring your tests and also making assertions.
We use the Jasmine-provided it function to define a spec. The first parameter of it is a text description of what the spec will be testing — in this case we have a defined component. The second parameter is a function that will run the test. We then use Jasmine's expect function to define our expectation.
Karma handles the process of creating HTML files, opening browsers and running tests and returning the results of those tests to the command line. If you use the Angular CLI to manage projects it automatically creates stub Jasmine spec files for you when generating code.
toEqual
makes a deep equality comparison. Which means that when all the properties of the objects' values are equal, the objects are considered to be equal.
As you said, you are using resource which adds a couple of properties to the objects in the array.
So this {id:12}
becomes this {id:12, $then: function, $resolved: true}
which are not equal. Id checking should be fine if you are just testing if you set the values properly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With