2017-01-14 29 views
0

我是新来的单元测试,请与我裸露。我无法调用贯穿到实际执行情况和我收到此错误:问题茉莉花间谍致电通过

TypeError: undefined is not an object (evaluating 'GitUser.GetGitUser('test').then') ... 

这里是我的代码:

app.controller('HomeController', ['$scope', 'GitUser', function ($scope, GitUser) { 
    $scope.name = "user"; 

    GitUser.GetGitUser('test').then(function (data) { 
     console.log(data); 
     if (data) { 
      $scope.name = data; 
     } 
    }); 
}]); 
app.factory('GitUser', function ($http) { 
    return { 
     GetGitUser: function (username) { 
      return $http.get('https://api.github.com/users/' + username) 
      .then(function success(response) { 
       return response.data.login; 
      }); 
     } 
    }; 
}); 

这里是我的单元测试:

describe('HomeController Unit Test', function() { 
    var $controllerConstructor, scope; 

    beforeEach(module("AngularApp")); 

    beforeEach(inject(function ($controller, $rootScope) { 
     $controllerConstructor = $controller; 
     scope = $rootScope.$new(); 
    })); 

    it('should test if scope.name is test', function() { 
     // Act 
     GitUser = { 
      GetGitUser: function() { } 
     }; 

     spyOn(GitUser, "GetGitUser").and.callThrough(); 

     GitUser.GetGitUser(); 

     $controllerConstructor('HomeController', { 
      '$scope': scope, 
      'GitUser': GitUser 
     }) 

     // Assert 
     expect(GitUser.GetGitUser).toHaveBeenCalled(); 
     expect(scope.name).toBe('test'); 
    }); 
}); 

任何建议或帮助将是巨大的!提前致谢!

回答

2

东西的问题不仅仅是一个缺少注入更多复杂一点...... 这里有一个调整的测试:

https://plnkr.co/edit/ZMr0J4jmLPtDXKpRvGBm?p=preview

有有几个问题: 1)你测试返回一个承诺的功能 - 所以你需要还嘲笑它的方式(例如通过使用回$q.when(..))。

2)你想测试这种情况发生时,创建你的控制器编码 -

GitUser.GetGitUser('test').then(function (data) { 
     console.log(data); 
     if (data) { 
      $scope.name = data; 
     } 
    }); 

应该被包裹在一个函数:

function init() { 
GitUser.GetGitUser('test').then(function (data) { 
     console.log(data); 
     if (data) { 
      $scope.name = data; 
     } 
    }); 
} 

,然后作出对提供您范围:

scope.init= init; 

然后在你的测试中调用函数并验证你的asse rtions。如果你不把它包装在一个函数中,它将不会被测试。

另外 - 模拟和callThrough事情...当你测试控制器(而不是服务)时,你可以使用callFake来代替 - callFake函数可以返回一个带有值的Promise(你想要的稍后验证) - 那么你可以确保智力游戏的控制器部分工作。

var name = 'test'; 
    // instead of trying to mock GitUser you can just callFake and be sure to return a promise 
    spyOn(GitUser, "GetGitUser").and.callFake(function() { 
     return $q.when(name); 
    }); 

我希望这一切是有道理的 - 在plunker应该把事情说清楚 - 我要在那里添加一些更多的评论。

+0

太棒了,这使得很多感觉!谢谢,当我有权访问该项目时,一定会尝试一下。我正在使用callThrough,所以我可以得到实际的登录用户名,看看它是否存在。我能测试控制器吗?还是必须为服务创建单元测试?@Birgit Martinelle –

+0

你应该为你的服务创建一个单独的测试来验证。对于那个测试,你会想使用$ httpBackend来模拟http调用(如果你是google $ httpBackend,你会看到一些例子,这里有一个例子:http://www.bradoncode.com/blog/2015/06/26/unit -testing-HTTP-ngmock基本面/ –

0

我觉得你只是错过这里

beforeEach(inject(function ($controller, $rootScope, _GitUser) { 
    $controllerConstructor = $controller; 
    scope = $rootScope.$new(); 
    GitUser = _GitUser; 
})); 
+0

它给了我这个错误,当我尝试过:错误:[$注射器:unpr]未知提供商:_GitUserProvider < - _GitUser –

+0

哦..尝试删除下划线? – digit