简体   繁体   English

如何使用Jasmine对链式方法进行单元测试

[英]How to unit test a chained method using Jasmine

I'm having a problem unit testing the following method: 我遇到问题单元测试以下方法:

 $scope.changeLocation = function (url) {
        $location.path(url).search({ ref: "outline" });
    };

I've written the following unit test that currently fails with this error (TypeError: Cannot read property 'search' of undefined): 我编写了以下单元测试,当前因此错误而失败(TypeError:无法读取未定义的属性'search'):

var $locationMock = { path: function () { }, search: function () { } };

it('changeLocation should update location correctly', function () {
        $controllerConstructor('CourseOutlineCtrl', { $scope: $scope, $location: $locationMock });

        var url = "/url/";
        spyOn($locationMock, "path");
        spyOn($locationMock, "search");

        $scope.changeLocation(url);

        expect($locationMock.search).toHaveBeenCalledWith({ ref: "outline" });
        expect($locationMock.path).toHaveBeenCalledWith(url);
    });

If I change my function to the following, the test passes: 如果我将我的功能更改为以下内容,则测试通过:

$scope.changeLocation = function (url) {
        $location.path(url);
        $location.search({ ref: "outline" });
    };

How do I unit test this method when I'm using method chaining? 当我使用方法链时,如何对此方法进行单元测试? Do I need to setup my $locationMock differently? 我需要以不同方式设置$ locationMock吗? For the life of me I cannot figure this out. 对于我的生活,我无法弄清楚这一点。

That is because your mock does not return location object to be able to chain through. 那是因为你的mock不会返回位置对象以便能够链接。 Using Jasmine 2.0 you can change your mock to: 使用Jasmine 2.0,您可以将模拟更改为:

var $locationMock = { path: function () { return $locationMock; }, 
                      search: function () { return $locationMock; } };

and

spyOn($locationMock, "path").and.callThrough();
spyOn($locationMock, "search").and.callThrough(); //if you are chaining from search

or add: 或添加:

spyOn($locationMock, "path").and.returnValue($locationMock);
spyOn($locationMock, "search").and.returnValue($locationMock); //if you are chaining from search

Or just create a spy object (less code): 或者只是创建一个间谍对象(更少的代码):

var $locationMock = jasmine.createSpyObj('locationMock', ['path', 'search']);

and

$locationMock.path.and.returnValue($locationMock);
$locationMock.search.and.returnValue($locationMock); //if you are chaining from search

try : 尝试:

spyOn($locationMock, "path").and.callThrough();

Else you'r calling search on a mock not $location 否则你会在模拟非$位置上调用搜索

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM