【问题标题】:TypeError Unit Test JasmineTypeError 单元测试 Jasmine
【发布时间】:2014-06-11 21:59:36
【问题描述】:

我需要一些帮助,我在实际阅读整个文件方面取得了一些进展,但是,我遇到了一个相当大的障碍(对我来说这很不错,我是新手)。我正在尝试模拟控制器的大部分内容,当我读取文件大约一半时遇到了问题,我不知道如何克服它。我将在下面包含尽可能多的代码。

LocationController.js

angular
.module('TDE')
.controller('LocationController', ['$rootScope', '$scope', '$location', '$window', '$document', 'LocationService', 'HeaderFooterService', 'SearchService', 'TranslationService', 'MTDE_CONFIG', 'LocationPartnerAssignmentService', 'ExperimentService', function ($rootScope, $scope, $location, $window, $document, $LocationService, $HeaderFooterService, $SearchService, $TranslationService, $MTDE_CONFIG, $LocationPartnerAssignmentService, $ExperimentService) {
//passes over this code

$scope.init = function () {
    // load dropdown for crop list

    // load dropdown for business partner list

    //load dropdown for experimenttype

    //load dropdown for IrrigationType
    //load dropdown for previousCrop

    var locationId = $SearchService.GetLocationId();
    $scope.LocationId=locationId;
    var experimentId = $SearchService.GetExperimentId();
    var experimentPartnerAssignmentId = $SearchService.GetExperimentPartnerAssignmentId();

    //load nitrogen value

    $ExperimentService.GetCrop(onSuccessCropCode,cropId);

    // get location detail from database
    if (locationId === "00000000-0000-0000-0000-000000000000") {
        // Load the Unassigned Location here
        $scope.IsAssinged = false;
    }
    else {
        $LocationService.Detail(onSuccessDetail, locationId);
    }

    // get growing year list
    $scope.GrowingYearList = $LocationService.GrowingYearList();
}

$scope.init(); //I NEED TO BE MOCKED SOMEHOW

Helper.js

ddescribe("Phases of Testing: The Journey", function () {

describe("Phase I: Test that Jasmine runs", function () {
    it("should test Jasmine is up", function () {
        expect(true).toBe(true);
    });
});

describe("Phase II: Try something", function () {
    var DBMock, SyncMock, baseMock, configMock, TransMock, loginMock, locMock, headerMock,
            searchMock, LPAMock, expMock, mockScope, $location, $scope, ctrl, initMock;
    beforeEach(function () {
        angular.mock.module('TDE');
        inject(function (_$location_, _$rootScope_, _$controller_) {
            $location = _$location_;
            $scope = _$rootScope_.$new();
            ctrl = _$controller_('LocationController', {
                '$scope': $scope
            });
        });
    });
    it("should be able to grab something", function () {
        expect(true).toBe(true);
        expect($scope).toBeDefined();
        expect($scope.PlantingDateNull()).toBeTruthy();
    });
  });
});

编辑: 现在问题归结为在最初定义后模拟 $scope.init() 函数调用。我在任何地方都找不到很好的帮助来源。

【问题讨论】:

    标签: javascript angularjs unit-testing jasmine


    【解决方案1】:

    应用:

    var myApp = angular.module('myApp', []);
    
    myApp.controller('MyCtrl', function ($scope, environment) {
        $scope.testValue = 'test environment';
    
        $scope.init = function() {
            $scope.testValue = 'development environment';
        };
    
        environment.development && $scope.init();
    });
    
    myApp.factory('environment', function() {
        return {
            development: true
        }
    });
    

    最重要的一行是environment.development && $scope.init();

    environment.development:

    • 如果评估为 TRUE - 将调用 $scope.inint()
    • 评估为 FALSE - 将阻止调用 $scope.inint()

    为了证明这一点,我要用两个值来存根这个服务

    测试:

    beforeEach(function () {
        module('myApp');
    });
    
    beforeEach(function () {
        module(function ($provide) {
            $provide.value('environment', mockEnvironment);
        });
    });
    
    describe('MyCtrl', function () {
        beforeEach(inject(function ($rootScope, $controller) {
            scope = $rootScope.$new();
            controllerInstantiate = $controller;
        }));
    
        it('prevents call .init() on test environment', function () {
            mockEnvironment.development = false;
            createController();
            expect(scope.testValue).toBe('test environment');
        });
    
        it('calls init on development environment', function () {
            mockEnvironment.development = true;
            createController();
            expect(scope.testValue).toBe('development environment');
        });
    
        function createController() {
            return controllerInstantiate('MyCtrl', {
                '$scope': scope
            });
        }
    });
    

    http://jsfiddle.net/krzysztof_safjanowski/2LUp3/

    【讨论】:

    • 非常感谢 Krzysztof 的帮助!我只是想诚实地清除那个错误。我一直在加载网页的 jasmine html 文件中包含所有文件。测试预先编写的代码真的很难,你说得对。我现在需要做的就是让它工作,这是我目前的项目。如果该问题线消失了(很接近),它就可以工作。
    • 你有什么错误?我认为$SearchService.GetLocationId 返回 cannot call GetLocationId on undefined 因为你没有为测试存根 $SearchService
    • 你可以忽略服务调用,这些都在加载,我有那些从 html 页面加载时进来的,很抱歉我不能发布非常有用的代码,因为这不完全是我的代码,而是组代码。你知道我怎么能忽略一行或嘲笑一行吗?它只是讨厌 $scope 的 .init() 部分。再次,很抱歉我不能提供更多帮助
    • 您不能从在实例化时调用的控制器进行模拟,如果在测试中设置了控制器,那么对于像 init() 这样的模拟方法来说为时已晚。如果你在控制器中运行.init() 之类的方法,你会觉得你没有在$routeProvide 上使用解析对象。换句话说 - 控制器有很多责任。
    • 天哪!再次感谢您的帮助。我会做更多的挖掘,因为是的,这个功能是一个障碍,没有它我可以移动,有了它我就卡住了。感谢您的所有帮助,Krzysztof!
    【解决方案2】:

    您必须为 $LocationService 而不是 LocationService 提供模拟,并为 Strips 方法创建间谍,例如:

    describe('myApp', function () {
    var scope,
    controller,
    $mockLocationService = {};
    
    beforeEach(function () {
        module('myApp');
    });
    
    beforeEach(function () {
        module(function ($provide) {
            $provide.value('$LocationService', $mockLocationService);
        });
    });
    
    describe('MyCtrl', function () {
        beforeEach(function () {
            $mockLocationService.Strips = jasmine.createSpy('$LocationService.Strips');
        });
    
        beforeEach(inject(function ($rootScope, $controller) {
            scope = $rootScope.$new();
            controller = $controller('MyCtrl', {
                '$scope': scope
            });
        }));
    
        it('calls Strips method', function () {
            expect($mockLocationService.Strips).toHaveBeenCalled();
        });
    });
    

    });

    答案与已编辑的问题不再相关,抱歉。

    【讨论】:

    • 这不起作用,它仍然给我与上面相同的错误。另外,您如何建议我为 $LocationService 进行模拟,我尝试更改它,但我需要 $provide.value('LocationService', lockMock); 行否则程序会因为它需要该提供程序而崩溃。
    • 在 Jasmine 1.3 版本更改后您身边的任何 cmet 吗?
    • 嘿,很抱歉这么久才回复您!我最近像上面提到的那样更新到 2.0。我已经清除了条带错误,但现在我遇到了一个问题,那就是阻止了不同的节目。我会编辑上面的帖子,也许你会有一个想法。给我几分钟。
    • 如果你能得到我会欣喜若狂的!它死在标有大注释的那一行。关于“ at new (file:LocationController.js:207:12)” 207:12 是标记的行!
    • 我已经回答了您的问题 - 如果没有问题 - 请查看它并添加一些声誉点。在正确答案后编辑问题是在浪费我的时间。根据 Jasmine 2.0 的更改,我愿意回答您的新问题
    猜你喜欢
    • 2015-06-29
    • 2017-04-04
    • 2013-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多