Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在Jasmine+;因果报应单元测试?_Javascript_Angularjs_Unit Testing_Karma Runner_Karma Jasmine - Fatal编程技术网

Javascript 如何在Jasmine+;因果报应单元测试?

Javascript 如何在Jasmine+;因果报应单元测试?,javascript,angularjs,unit-testing,karma-runner,karma-jasmine,Javascript,Angularjs,Unit Testing,Karma Runner,Karma Jasmine,因此,我目前正在用Jasmine+Karma测试AngularJS中的一个函数。我正在尝试创建一个对象,并查看它是否已成功添加到数据库中。这个函数调用另一个异步函数,我在测试中似乎无法解释这一点。我知道它从未被呼叫过,因为我没有从它那里得到任何回报。没有控制台日志、错误或任何内容。到目前为止,我有一个名为StoringService的服务,看起来像: myApp.service("StoringService", function($http){ // Stores my object

因此,我目前正在用Jasmine+Karma测试AngularJS中的一个函数。我正在尝试创建一个对象,并查看它是否已成功添加到数据库中。这个函数调用另一个异步函数,我在测试中似乎无法解释这一点。我知道它从未被呼叫过,因为我没有从它那里得到任何回报。没有控制台日志、错误或任何内容。到目前为止,我有一个名为StoringService的服务,看起来像:

myApp.service("StoringService", function($http){

    // Stores my object
    this.store = function(object,success,error){
        var request = {
            method: "post",
            url: "example.com",
            headers: {/*...*/},
            data: object.toJSON()
        };
        $http(request).then(
            function(response){
                console.log("Success! Yay!");
                success(response.data.url.script);
            },function(response){
                console.log("Error! Bummer...");
                error(response);
            }
        );
    };
});
我正在测试的主控制器是我的CreationController。它有一个名为Submit的函数,该函数调用上述服务。这在运行应用程序时有效,但在运行测试时似乎无效。submit方法(CreationController内部)如下所示:

myApp.controller("CreationController", ["$scope","StoringService",
    function($scope,StoringService){

        $scope.newObject = new Object();
        $scope.successAlert = false; // changed by success() in StoringService
        $scope.errorAlert = false; // changed by error() in StoringService

        $scope.submit = function(){
            StoringService.store($scope.newObject,
                function(message){
                    console.log(message);
                },
                function(error){
                    console.log(error);
                }
            );
        }
}]);
最后,当我进行Jasmine+Karma测试时,我注意到我的对象没有被创建,经过进一步的检查,我的StoringService在实际的$http请求之前工作正常(示例代码中的第11行)。我不完全确定如何触发这一行动。这就是目前我的测试的样子

//creation_test.js
var scope, service;

describe('Creation Test', function(){
    originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
    jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;

    beforeEach(module('MyApplication'));
    beforeEach(inject($rootScope, $controller, $injector){

        scope = $rootScope.$new();
        service = $injector.get('StoringService');

        $controller('CreationController',{
            $scope: scope,
            StoringService: service
        });
    }));

    // Fails but should pass
    it('should create an object',function(done){
        scope.newObject.name = "new_object";
        scope.newObject.data = "object data";
        scope.submit();
        setTimeout(function(){
            expect(scope.successAlert).toBe(true);
            expect(scope.errorAlert).toBe(false);
            done();
        },5000);
    });

    afterEach(function(){
        jasmine.DEFAULT_TIMEOUT_INTERVL = originalTimeout;
    });
);

我不完全确定这为什么不起作用,或者如何确切地修复它。successAlert和errorAlert的值从未更改,这使我相信$http请求从未被调用。我一直在尝试可能的解决方案,但到目前为止,还没有解决这个问题。如果有人能帮我解决这个问题,我将不胜感激。

这里是一个有效的例子。下面的测试确保您正在使用args调用服务方法

expect(loginService.authenticate).toHaveBeenCalledWith({
          user: 'david@yahoo.com',
          pass: '123'
        });

我已经调整了你的测试。当进行单元测试时,我们不想花时间调用后端,这就是为什么我们需要模拟HTTP调用。当您的
store
方法返回承诺时,我们在单元测试中模拟此行为,创建一个我们可以控制的延迟承诺。稍后,您可以
解决
拒绝
测试成功与错误的承诺。我希望有帮助

describe('Controller: CreationController', function() {

  beforeEach(module('MyApplication'));

  var storingService;
  var deferred;
  // Mock services and spy on methods
  beforeEach(inject(function($q, StoringService) {
    deferred = $q.defer();
    storingService = StoringService;
    spyOn(storingService, 'store').and.returnValue(deferred.promise);
  }));

  var CreationController;
  var scope;
  // Initialize the controller and a mock scope
  beforeEach(inject($rootScope, $controller) {
    scope = $rootScope.$new();
    CreationController = $controller('CreationController', {
      $scope: scope,
      StoringService: storingService
    });
  }));

  it('should create an object', function() {
    scope.submit();
    scope.$apply(function() {
      deferred.resolve();
    });
    expect(scope.successAlert).toBe(true);
    expect(scope.errorAlert).toBe(false);
  });

);

你想测试什么?我没有看到
CreationController
创建任何对象……我只是尝试测试对象是否成功地进入数据库。我遗漏了那个代码,因为我不知道是否有必要。但是一个空白对象看起来就像对象{name:,data:,timestamp:}。使用表单,用户将填写姓名和数据字段并提交到数据库。您尝试做的是e2e测试,这通常不需要在Karma中执行。角度单元测试假定不执行任何实际请求。应该有两个测试-一个用于模拟服务的控制器单元,另一个用于模拟$http响应的服务单元。单元测试测试单个单元,因此得名。它们不是“一体式”测试。