简体   繁体   English

茉莉花测试多个间谍

[英]Jasmine testing multiple spies

I'm writing a few tests for an Angular application, these are my first stab at unit tests for Angular using Jasmine. 我正在为Angular应用程序编写一些测试,这是我使用Jasmine进行Angular单元测试时的第一次尝试。 I'm having trouble structuring the test to cater for the various scenarios inside the function (namely the if statement and callbacks). 我在构造测试以适应函数内部的各种情况时遇到麻烦(即if语句和回调)。

Here's my $scope function, which takes an Object as an argument, and if that object has an id , then it updates the object (as it'll already exist), otherwise it creates a new report and pushes to the backend using the CRUD service. 这是我的$ scope函数,该函数接受一个Object作为参数,如果该对象具有id ,则它将更新该对象(因为它已经存在),否则它将创建一个新报告并使用CRUD推送到后端服务。

$scope.saveReport = function (report) {
  if (report.id) {
    CRUD.update(report, function (data) {
      Notify.success($scope, 'Report updated!');
    });
  } else {
    CRUD.create(report, function (data) {
      $scope.report = data;
      Notify.success($scope, 'Report successfully created!');
    });
  }
};

My test so far passes in a fake Object with an id so it'll trigger the CRUD.update method, which I then check is called. 到目前为止,我的测试通过了一个带有id的伪造对象,它将触发CRUD.update方法,然后我检查该方法。

describe('$scope.saveReport', function () {
  var reports, testReport;
  beforeEach(function () {
    testReport = {
      "id": "123456789",
      "name": "test"
    };
    spyOn(CRUD, 'update');
    $scope.saveReport(testReport);
  });
  it('should call CRUD factory and update', function () {
    expect(CRUD.update).toHaveBeenCalledWith(testReport, jasmine.any(Function));
  });
});

I understand Jasmine doesn't allow multiple spies, but I want to be able to somehow test for the if condition, and run a mock test for when the Object doesn't pass in an Object too: 我知道Jasmine不允许多个间谍,但是我希望能够以某种方式测试if条件,并在对象也没有通过Object时运行模拟测试:

describe('$scope.saveReport', function () {
  var reports, testReport;
  beforeEach(function () {
    testReport = {
      "id": "123456789",
      "name": "test"
    };
    testReportNoId = {
      "name": "test"
    };
    spyOn(CRUD, 'update');
    spyOn(CRUD, 'create'); // TEST FOR CREATE (NoId)
    spyOn(Notify, 'success');
    $scope.saveReport(testReport);
    $scope.saveReport(testReportNoId); // TEST FOR NO ID
  });
  it('should call CRUD factory and update', function () {
    expect(CRUD.update).toHaveBeenCalledWith(testReport, jasmine.any(Function));
    // UNSURE ON THIS PART TOO
  });
});

I've read things about using the .andCallFake() method, but I could not see how this could work with my setup. 我已经阅读了有关使用.andCallFake()方法的内容,但是我看不到它如何与我的设置一起使用。 Any help really appreciated. 任何帮助真的很感激。

It seems that you should decide on what you need to test first. 看来您应该先决定要测试什么。 If you want to test simply that update is called when id exists or create is called when it does not then you should just structure the it function with those conditions. 如果您只想测试id存在时调用update或不存在时调用create,则应该使用这些条件构造it函数。 The before each is the wrong place for some of those things. 对于某些事情,每个之前都是错误的地方。

it('should call CRUD factory and update', function () {
    spyOn(CRUD, 'update');
    $scope.saveReport(testReport);
    expect(CRUD.update).toHaveBeenCalledWith(testReport, jasmine.any(Function));
});
it('should call CRUD create', function() {
    spyOn(CRUD, 'create');
    $scope.saveReport(testReportNoId); // TEST FOR NO ID
    expect(CRUD.create).toHaveBeenCalledWith(testReport, jasmine.any(Function));
});

Only put things in the before each that you actually should do before each test. 只能在每次测试之前实际应该做的事情之前放东西。

Hope this helped! 希望这对您有所帮助!

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

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