为Angular编写代码以允许单元测试的正确方法

时间:2016-07-26 21:42:52

标签: angularjs unit-testing angular-controller

我很难理解我应该如何为Angular.js控制器编写方法以允许完成单元测试。互联网上的所有教程都很简单,并没有显示它在现实生活中的应用程序。那些教程显示所有方法都是通过将它们附加到“scope”或“this(aka vm)”来公开的。根据我的理解,不需要暴露不在控制器外部使用的方法。在下面的示例中,我只暴露了两种方法,因为它们是通过单击页面上的按钮触发的。其余方法仅用于内部目的。 如何测试控制器中的私有方法而不暴露它们?我是否需要公开所有这些才能进行单元测试?揭露所有方法是一种好习惯吗?谢谢

angular.module('app.pool',[])
  .controller('PoolController', PoolController);

function PoolController(PoolService) {
    var vm = this;

    vm.candidateName='';
    vm.candidatePicUrl='';

    vm.approveCandidate = approveCandidate;
    vm.refuseCandidate = refuseCandidate;

    function approveCandidate() {
        PoolService.approveCandidate();
        getNextCandidate();
    }

    function refuseCandidate() {
        PoolService.refuseCandidate();
        getNextCandidate();
    }

    function getNextCandidate() {
        clearProfile();
        PoolService.getNextCandidate().
        success(displayUserData);
    }

    function displayUserData(data) {
        vm.candidateName = getCandidateName(data);
        vm.candidatePicUrl = getCandidateProfilePic(data);
    }

    function getCandidateName(data) {
        return data.userName;
    }

    function getCandidateProfilePic(data) {
        return changeUrlToBiggerPic(data.profilePicture);
    }

    function changeUrlToBiggerPic(url) {
        return url.replace('s150x150', 's600x600');
    }

    function clearProfile() {
        vm.candidateName = "";
        vm.candidatePicUrl = "";
    }

}

2 个答案:

答案 0 :(得分:1)

仅仅为了单元测试而暴露私有方法绝对不是一个好主意。

您应该能够通过期望特定输出来测试这些方法正在做什么。

例如:

  • 检查范围变量是否已设置为预期值。
  • 确保使用正确的输入调用了提供的依赖项(间谍)。

答案 1 :(得分:0)

它总是取决于案例,但是,通常公开私有类方法是一个好主意。

可以使用_前缀约定命名私有方法,以区别于公共方法,并可选择使用Object.defineProperty进行不可枚举。

JavaScript无法反映私有成员(本地变量)。除了作为基本的OOP原则和一般的“好事”之外,封装还会损害JS中的可测试性,并且几乎没有什么可以作为回报。

封装不会为JS应用程序增加安全性,将单元视为黑盒也无济于事。另一方面,将间谍放在每个被调用的方法上都有帮助。