My ng app is working fine, but I am trying to write a ngMock test for my controller; I am basically following along the example on angular's website: https://docs.angularjs.org/api/ngMock/service/$httpBackend
The problem I am running into is that it complains about unexpected request even when request is being expected.
PhantomJS 1.9.8 (Windows 8 0.0.0) NotificationsController should fetch notification list FAILED
Error: Unexpected request: GET Not valid for testsapi/AspNetController/AspNetAction Expected GET api/AspNetController/AspNetAction
What I do not get is that, on the error line, why is there a "tests" word appended before my service url? I thought it should be sending to 'api/AspNetController/AspNetAction' What am I doing wrong here. I can't find any one else running into the same problem as me through google.
Edit: I noticed that, if i remove the sendRequest portion from my controller, and have the unit test log my request object in console, i see the following json.
{
"method":"GET",
"url":"Not valid for testsapi/AspNetController/AspNetAction",
"headers":{
"Content-Type":"application/json"
}
}
here is the controller code
angular.module('MainModule')
.controller('NotificationsController', ['$scope', '$location', '$timeout', 'dataService',
function ($scope, $location, $timeout, dataService) {
//createRequest returns a request object
var fetchNotificationsRequest = dataService.createRequest('GET', 'api/AspNetController/AspNetAction', null);
//sendRequest sends the request object using $http
var fetchNotificationsPromise = dataService.sendRequest(fetchNotificationsRequest);
fetchNotificationsPromise.then(function (data) {
//do something with data.
}, function (error) {
alert("Unable to fetch notifications.");
});
}]
);
Test code
describe('NotificationsController', function () {
beforeEach(module('MainModule'));
beforeEach(module('DataModule')); //for data service
var $httpBackend, $scope, $location, $timeout, dataService;
beforeEach(inject(function ($injector) {
$httpBackend = $injector.get('$httpBackend');
$scope = $injector.get('$rootScope');
$location = $injector.get('$location');
$timeout = $injector.get('$timeout');
dataService = $injector.get('dataService');
var $controller = $injector.get('$controller');
createController = function () {
return $controller('NotificationsController', {
'$scope': $scope,
'$location': $location,
'$timeout': $timeout,
'dataService': dataService,
});
};
}));
afterEach(function () {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
it('should fetch notification list', function () {
$httpBackend.expectGET('api/AspNetController/AspNetAction'); //this is where things go wrong
var controller = createController();
$httpBackend.flush();
});
});
Data service code
service.createRequest = function(method, service, data) {
var req = {
method: method, //GET or POST
url: someInjectedConstant.baseUrl + service,
headers: {
'Content-Type': 'application/json'
}
}
if (data != null) {
req.data = data;
}
return req;
}
service.sendRequest = function (req) {
return $q(function (resolve, reject) {
$http(req).then(function successCallback(response) {
console.info("Incoming response: " + req.url);
console.info("Status: " + response.status);
console.info(JSON.stringify(response));
if (response.status >= 200 && response.status < 300) {
resolve(response.data);
} else {
reject(response);
}
}, function failCallback(response) {
console.info("Incoming response: " + req.url);
console.info("Error Status: " + response.status);
console.info(JSON.stringify(response));
reject(response);
});
});
}
ANSWER:
since dataService created the finalized webapi url by someInjectedConstant.baseUrl + whatever_relative_url passed in from controller, In the test that I am writting, I will have to inject someInjectedConstant and
$httpBackend.expectGET(someInjectedConstant.baseUrl + relativeUrl)
instead of just doing a $httpBackend.expectGET(relativeUrl)