我正在尝试使用注入组件的服务来调用Github API - 是的,我使用的是AngularJS 1.5.3。
在单元测试中,我没有收到一个值(当我在浏览器中运行时,该功能会起作用)。我不确定我做错了什么,希望有人能指出我正确的方向。
main.component.js
(function(){
angular.module("app").component("mainComponent", {
templateUrl: "/templates/main.component.html",
controllerAs: "vm",
controller: function(APIFactory, UserFactory, $state){
const vm = this;
vm.searchGithub = function(){
APIFactory.getAPI(vm.searchText).then(function(res){
res.status !== 200 ? $state.go("404", {errorData: res.data }) : (
vm.User = new UserFactory.User(res.data),
$state.go("profile", {userData: vm.User})
);
})
.catch(function(err){
$state.go("fourOFour");
});
};
}
});
})();
main.component.spec.js
describe("Main Component", function(){
var mainComponent, APIFactory, UserFactory, $httpBackend, $q, $state, $rootScope;
const addy = "https://api.github.com/users/";
beforeEach(angular.mock.module("app"));
beforeEach(inject(function(_APIFactory_, _UserFactory_, _$httpBackend_, _$state_, _$q_, _$rootScope_, _$componentController_){
APIFactory = _APIFactory_;
UserFactory = _UserFactory_;
$httpBackend = _$httpBackend_;
$state = _$state_;
$q = _$q_;
$rootScope = _$rootScope_;
$rootScope.$new();
mainComponent = _$componentController_("mainComponent", { $scope : {} });
}));
describe("Checking if the searchGithub() worked correctly", function(){
var result;
beforeEach(function(){
spyOn(mainComponent, "searchGithub").and.callThrough();
spyOn(APIFactory, "getAPI").and.callThrough();
result = {};
});
it("should make a call to UserFactory", function(){
mainComponent.searchText = "someName";
expect(mainComponent.searchText).toBeDefined();
// RESPONSE_SUCCESS does exist, I've omitted it.
$httpBackend.whenGET(addy + mainComponent.searchText).respond(200, $q.when(RESPONSE_SUCCESS));
// This is where I expect something to work
APIFactory.getAPI(mainComponent.searchText).then(function(res){
result = res;
});
$httpBackend.flush();
expect(APIFactory.getAPI).toHaveBeenCalledWith(mainComponent.searchText);
expect(mainComponent.User).toBeDefined();
});
});
});
答案 0 :(得分:0)
所以这就是我提出的解决方案。如果有人想给我一个更好的解决方案,我就是想要的。
首先,我制作了两个嘲讽,然后将它们注入mainComponent
,并将其作为我的模拟APIFactoryMock.getAPI
函数的间谍:
const APIFactoryMock = {
getAPI: function(){}
};
const UserFactoryMock = {
User: function(data){
return {
login: data.login,
id: data.id,
avatar_url: data.avatar_url,
html_url: data.html_url,
followers: data.followers,
following: data.following,
public_repos: data.public_repos,
public_gists: data.public_gists,
created_at: data.created_at,
updated_at: data.updated_at,
name: data.name,
company: data.company,
blog: data.blog,
location: data.location,
bio: data.bio,
hireable: data.hireable,
email: data.email,
links: {
followers_url: data.followers_url,
following_url: data.following_url,
subscriptions_url: data.subscriptions_url,
repos_url: data.repos_url,
organizations_url: data.organizations_url
}
}
}
};
beforeEach(inject(function(_APIFactory_, _UserFactory_, _$httpBackend_, _$state_, _$q_, _$rootScope_, _$componentController_){
APIFactory = _APIFactory_;
UserFactory = _UserFactory_;
$httpBackend = _$httpBackend_;
$state = _$state_;
$q = _$q_;
$rootScope = _$rootScope_;
$rootScope.$new();
spyOn(APIFactoryMock, "getAPI").and.returnValue(RESPONSE_SUCCESS);
bindings = { APIFactory: APIFactoryMock, UserFactory: UserFactoryMock, $state: $state };
mainComponent = _$componentController_("mainComponent", { $scope : {} }, bindings);
}));
然后我为嘲笑写了测试:
it("should make a call to UserFactory", function(){
mainComponent.searchText = "someName";
expect(mainComponent.searchText).toBeDefined();
mainComponent.searchGithub(mainComponent.searchText);
$httpBackend.whenGET(addy + mainComponent.searchText).respond(200, $q.when(RESPONSE_SUCCESS));
$httpBackend.flush();
mainComponent.User = UserFactoryMock.User(RESPONSE_SUCCESS.data);
expect(mainComponent.searchGithub).toHaveBeenCalledWith(mainComponent.searchText);
expect(mainComponent.User).toBeDefined();
expect(mainComponent.User.id).toEqual(666);
});
答案 1 :(得分:0)
在上面的答案中,您手动调用测试用例中的UserFactoryMock.User
,这将创建一个用户对象。
但要正确测试功能,应该在调用UserFactory.User
成功时检查是否要调用APIFactory.getAPI
(不在测试用例中手动调用UserFactory.User
。< / p>
我建议将测试用例修改为以下内容:
describe("Main Component", function(){
var mainComponent, APIFactory, UserFactory, $httpBackend, $q, $state, $rootScope;
const addy = "https://api.github.com/users/";
beforeEach(angular.mock.module("app"));
beforeEach(inject(function(_APIFactory_, _UserFactory_, _$httpBackend_, _$state_, _$q_, _$rootScope_, _$componentController_){
APIFactory = _APIFactory_;
UserFactory = _UserFactory_;
$httpBackend = _$httpBackend_;
$state = _$state_;
$q = _$q_;
$rootScope = _$rootScope_;
var scope = $rootScope.$new();
var bindings = { APIFactory: APIFactory, UserFactory: UserFactory, $state: $state };
mainComponent = _$componentController_("mainComponent", { $scope : scope }, bindings);
}));
describe("Checking if the searchGithub() worked correctly", function(){
var result;
beforeEach(function(){
spyOn(mainComponent, "searchGithub").and.callThrough();
spyOn(APIFactory, "getAPI").and.callFake(function() {
var def = $q.defer();
def.resolve(RESPONSE_SUCCESS);
return def.promise;
});
spyOn(UserFactory, "User").and.callFake(function() {
var user = { id: 666, .... };
return user;
});
});
it("should make a call to UserFactory", function(){
mainComponent.searchText = "someName";
$rootScope.$apply();
expect(mainComponent.searchText).toBeDefined();
mainComponent.searchGithub(); // Call the same way as it works in the code actually.
$rootScope.$apply();
//No manual call to 'UserFactory.User' or 'APIFactory.getAPI'. The call to 'APIFactory.getAPI' is resolved/succeeds, hence a call to 'UserFactory.User' is made and the same is tested
expect(APIFactory.getAPI).toHaveBeenCalledWith(mainComponent.searchText);
expect(UserFactory.User).toHaveBeenCalledWith(RESPONSE_SUCCESS.data);
expect(mainComponent.User).toBeDefined();
expect(mainComponent.User.id).toEqual(666);
});
});
});