4

单元测试:

"use strict";

var usersJSON = {};

describe("mainT", function () {


 var ctrl, scope, httpBackend, locationMock, 

    beforeEach(module("testK"));
    beforeEach(inject(function ($controller, $rootScope, $httpBackend, $location, $injector) {
        scope = $rootScope.$new();
        httpBackend = $httpBackend;
        locationMock = $location;

        var lUrl = "../solr/users/select?indent=true&wt=json",
        lRequestHandler = httpBackend.expect("GET", lUrl);          
        lRequestHandler.respond(200, usersJSON);     

        ctrl = $controller("mainT.controller.users", { $scope: scope, $location: locationMock});
        httpBackend.flush();
        expect(scope.users).toBeDefined();

    }));

    afterEach(function () {
        httpBackend.verifyNoOutstandingRequest();
        httpBackend.verifyNoOutstandingExpectation();
    });




        describe("method test", function () {
        it('should test', function () {
            expect(true).toBeFalsy();
        });
    });
});

我正在测试的控制器(工作):init 中的异步函数给我带来了麻烦(使用 ../solr/users/select?indent=true&wt=json):

 $scope.search = function () {
                    var lStart = 0,
                        lLimit = privates.page * privates.limit;


                    Search.get({
                        collection: "users",
                        start: lStart,
                        rows: lLimit)
                    }, function(records){
                        $scope.users= records.response.docs;
                    });
                };

我认为会发生什么:
1. 通知后端他将收到什么请求
2. 通知后端以空 JSON 响应该请求
3. 创建一个控制器(Search.get get 执行)
4. 通知后端接收所有请求并回答它们(冲洗)

但是我总是收到以下错误:

Error: Unexpected request: GET : ../solr/users/select?indent=true&wt=json

我没有很好地处理异步搜索功能吗?这应该怎么做?

4

3 回答 3

3

这不是真正的“单元”测试,它更像是一种行为测试。

这应该是几个测试:

  1. 测试您的服务 Search.get 以确保调用正确的 URL 并返回结果。
  2. 测试您的控制器方法以确保它正在调用 Search.get
  3. 测试您的控制器方法以确保将结果放在正确的位置。

您发布的代码有点不完整,但这里有两个单元测试应该涵盖您:

这是我在博客中广泛讨论的内容,并且条目更详细:

这是我正在谈论的一个例子:

describe('Search', function () {
    var Search,
        $httpBackend;

    beforeEach(function () {
        module('myModule');

        inject(function (_Search_, _$httpBackend_) {
            Search = _Search_;
            $httpBackend = _$httpBackend_;
        });
    });

    describe('get()', function () {
        var mockResult;

        it('should call the proper url and return a promise with the data.', function () {
            mockResult = { foo: 'bar' };
            $httpBackend.expectGET('http://sample.com/url/here').respond(mockResult);

            var resultOut,
                handler = jasmine.createSpy('result handler');
            Search.get({ arg1: 'wee' }).then(handler);

            $httpBackend.flush();

            expect(handler).toHaveBeenCalledWith(mockResult);

            $httpBackend.verifyNoOutstandingRequest();
            $httpBackend.verifyNoOutstandingExpectation();


        });
    });

});

describe('myCtrl', function () {
    var myCtrl,
        $scope,
        Search;

    beforeEach(function () {
        module('myModule');

        inject(function ($rootScope, $controller, _Search_) {
            $scope = $rootScope.$new();
            Search = _Search;
            myCtrl = $controller('MyCtrl', {
                $scope: scope
            });
        });
    });

    describe('$scope.foo()', function () {
        var mockResult = { foo: 'bar' };

        beforeEach(function () {
            //set up a spy.
            spyOn(Search, 'get').andReturn({
                then: function (fn) {
                    // this is going to execute your handler and do whatever
                    // you've programmed it to do.. like $scope.results = data; or
                    // something.
                    fn(mockResult);
                }
            });

            $scope.foo();
        });

        it('should call Search.get().', function () {
            expect(Search.get).toHaveBeenCalled();
        });

        it('should set $scope.results with the results returned from Search.get', function () {
            expect(Search.results).toBe(mockResult);
        });
    });

});
于 2013-09-27T17:03:38.847 回答
2

lUrl在单元测试中,不应该是相对路径,即,而不是 "../solr/users/select?indent=true&wt=json" 它应该是绝对的 "/solr/users/select?indent=true&wt =json”。所以如果你的应用程序运行在"http://localhost/a/b/index.html"lUrl应该是"/a/solr/..."

请注意,您也可以在 中使用正则表达式$httpBackend.expectGET(),如果您不完全确定以后的绝对路径会是什么样子,这可能会有所帮助。

于 2013-09-23T21:46:24.317 回答
2

在 BeforeEach 中,您应该使用 httpBackend.when 而不是 httpBackend.expect。我认为你不应该在你的 BeforeEach 中有一个断言(期望),所以应该把它移到一个单独的 it() 块中。我也看不到 lRequestHandler 的定义位置。默认情况下发送 200 状态,因此不需要。您的 httpBackend 行应如下所示:

httpBackend.when("GET", "/solr/users/select?indent=true&wt=json").respond({});

你的测试应该是:

    describe("method test", function () {
        it('scope.user should be defined: ', function () {
            expect(scope.user).toEqual({});
        });
    });
于 2013-09-26T23:45:22.967 回答