Reputation: 373
I'm trying to learn angular unit test with $resource.
Here I have a simple controller :
.controller('DictionaryCtrl', function ($scope, DictionaryService) {
$scope.jSearchDictionary = function () {
$scope.word = DictionaryService.getByJword({ jp: $scope.jword });
}
$scope.eSearchDictionary = function () {
$scope.word = DictionaryService.getByEword({ eng: $scope.eword });
}
})
In my view, I have 2 ng-submit (jSearchDictionary and eSearchDictionary) and i bind the corresponding word that is searched ( jword or eword ).
The service is also quite simple :
.factory('DictionaryService', function ($resource) {
return $resource('http://127.0.0.1:3000/api/nlp/words', {}, {
getByJword: { method: 'GET', params: { jp: '@jword' } },
getByEword: { method: 'GET', params: { en: '@eword' } },
})
})
Finally, here is my test.
describe('Controller: nlpCtrl', function () {
beforeEach(function () {
this.addMatchers({
toEqualData: function (expected) {
return angular.equals(this.actual, expected);
}
});
});
beforeEach(module('gakusei'));
describe('nlpCtrl', function () {
var scope,
$controller,
$httpBackend,
$stateParams,
Eword,
mockWord = [
{
"words": [
{
"readings": [
"ホッケー"
]
}
],
"count": 1
}];
beforeEach(inject(function (_$httpBackend_, $rootScope, _$controller_) {
scope = $rootScope.$new();
$controller = _$controller_;
$httpBackend = _$httpBackend_;
}));
afterEach(function () {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
it('should get a word', inject(function (DictionaryService) {
Eword = "englishWord";
$httpBackend.expectGET('http://127.0.0.1:3000/api/nlp/words?eng=englishWord')
.respond(mockWord[0]);
var ctrl = $controller('DictionaryCtrl', { $scope: scope });
var request = DictionaryService.getByEword({ eng: Eword })
$httpBackend.flush();
expect(scope.word).toEqualData(mockWord[0]);
expect(BasketService.getByJword).toBeTruthy();
expect(BasketService.getByEword).toBeTruthy();
}));
});
});
The problem is at the line :
expect(scope.word).toEqualData(mockWord[0]);
scope.word being undefined. Unit Testing is way over my head right now, I'm not sure of what I'm doing at all. If you have a solution to this particular problem, have any advices at all concerning all the code or are willing to message me and guide me a little, that would be awesome.
Upvotes: 1
Views: 1509
Reputation: 123739
You have couple issues in your expectation and set up.
1) You are testing a controller and its scope, so do actions on the controller methods and set values on controller scope.
2) Instead of doing Eword = "englishWord";
you should set the value on the controller scope scope.eword = "englishWord";
3) Instead of calling service method directly DictionaryService.getByEword({ eng: Eword })
, you need to invoke the method on the scope, i.e scope.eSearchDictionary();
so that when the method is resolved it resolves with respective data and sets it on the scope.
4) Note that when you test against scope.word
directly you may not get desired result since the result object will have additional properties like $promise
on it. Since you are directly assigning the results.
5) I am not sure if you need the last 2 expectations at all.
Try:-
it('should get a word', inject(function (DictionaryService) {
scope.eword = "englishWord";
$httpBackend.expectGET('http://127.0.0.1:3000/api/nlp/words?eng=englishWord')
.respond(mockWord[0]);
$controller('DictionaryCtrl', { $scope: scope });
scope.eSearchDictionary();
$httpBackend.flush();
expect(scope.word.words[0]).toEqual(mockWord[0].words[0]);
/*I dont think you need the following expectations at all*/
expect(DictionaryService.getByJword).toBeDefined();
expect(DictionaryService.getByEword).toBeDefined();
}));
Some syntax of expectation utility method is different from what you are using, you can use the same that you use, i just did it for the demo
Upvotes: 1
Reputation: 6620
The variable you are looking for does not exist outside of those two functions. Try defining it at the top of your controller like so:
.controller('DictionaryCtrl', function ($scope, DictionaryService) {
$scope.word = '';
$scope.jSearchDictionary = function () {
$scope.word = DictionaryService.getByJword({ jp: $scope.jword });
}
$scope.eSearchDictionary = function () {
$scope.word = DictionaryService.getByEword({ eng: $scope.eword });
}
})
Upvotes: 0