1

我很难理解如何解决单元测试控制器的问题,该控制器在初始化期间会进行 GET 调用。

在测试执行 POST 请求的控制器方法时,由于初始 GET 调用,我在测试中收到以下错误:

错误:意外请求:GET

控制器的主要部分如下所示:

.controller('someController', function($scope, $http, $log) {

    $scope.posts = [];

    $scope.content = '';

    $scope.read = function() {

        $http.get('/read.php')

            .success(function(data) {

                $scope.posts = data;

            })

            .error(function(data, status, headers, config) {

                throw new Error('Something went wrong with reading data');

            });

    };


    $scope.read();


    $scope.write = function() {

        $http({
            method: 'POST',
            url: '/write.php',
            data: "content=" + $scope.content,
            headers: {'Content-Type': 'application/x-www-form-urlencoded'}
        })
            .success(function(data) {

                $scope.posts.push({ id : data.id, task : $scope.content })

            })
            .error(function(data, status, headers, config) {

                throw new Error('Something went wrong with writing data');

            });

    };

});

如您所见,我在定义后立即调用 read() 方法 - 以便在页面加载时从数据库中获取所有记录。

我已经对 .config() 或其他服务进行了同样的尝试,但显然结果是相同的。

现在 - 我的测试如下:

describe('someController tests', function() {


    var $scope,
        $http,
        $httpBackend,
        $log;


     beforeEach(function() {

        module('myApp');

        inject(function($rootScope, _$http_, _$httpBackend_, _$log_) {

            $scope = $rootScope.$new();
            $http = _$http_;
            $httpBackend = _$httpBackend_;
            $log = _$log_;

        });


        $httpBackend.expectGET("/mod/read.php").respond({});


    });



    it('should add new record', inject(function($controller) {

        $controller('ToDoController', {

            $scope : $scope,
            $http : $http,
            $log : $log

        });


        $scope.posts = [];

        $scope.content = 'Some content';

        $httpBackend
            .whenPOST('/write.php')
            .respond({ id : 1, content : $scope.content });


        $scope.write();        

        $httpBackend.flush();     


        expect($scope.posts.length).toBe(1);


        afterEach(function() {

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

        });

    }));



});

现在 - 我对这段代码有几个问题。

  1. 在页面加载时调用控制器中的方法是否被认为是一种好习惯?我知道如果我在文档中使用 ng-init 来调用它——这将解决我所有的问题,但我只是不喜欢这种方法。

  2. 在我调用的测试的 beforeEach() 方法中:

$httpBackend.expectGET("/mod/read.php").respond({});

在初始化期间反映 read() 方法的调用,但同样 - 我不确定这是正确的做法。我知道如果我删除它 - “应该添加新记录”测试将失败并出现上述错误。

  1. 我知道 afterEach() 应该放在 it() 块之外,但是如果我这样做 - 它会导致同样的问题,但是错误将适用于这个 describe 块中的所有测试。将它放在 it() 块内是否被认为是一种不好的做法/不正确?

  2. 如果在 beforeEach() 循环中已经触发了调用,我将如何执行 read() 测试?

  3. 最后 - 你有什么建议来改进/重写控制器和测试以确保它发挥最佳效果?

我对 TDD 很陌生——所以我确信这只是我对这个主题的有限理解,但希望能得到一些建设性的帮助。

4

0 回答 0