使用Jasmine为ng-click事件添加基本控制器的测试用例

时间:2017-01-02 15:01:49

标签: angularjs jasmine karma-jasmine

我正试着把业力放在karma-jasmine上,我正在研究一些基本的例子。

I have created one small plnkr只做两件事:

  1. 添加数字
  2. 在按钮上单击
  3. 显示一些硬编码值

    这是我的public void startRecording() throws IOException { ditchRecord(); File outFile=new File(OUTPUT_FILE); if(outFile.exists()){ outFile.delete(); } recorder= new MediaRecorder(); recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL); recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); recorder.setOutputFile(OUTPUT_FILE); recorder.prepare(); recorder.start(); } private void ditchRecord() { if(recorder!=null) recorder.release(); }

    MainController.spec.js

    对于附加的plnkr中提到的控制器,我想我应该只测试两件事:

    1. 测试添加是否正常。
    2. 测试按钮后的数据是否正确
    3. 问题:

      1. 取消注释上述任何一行线索错误
      2.   

        Chrome 55.0.2883(Windows 7 0.0.0)主控制器add()应正确分配值失败

             
            

        已经调用了预期的间谍添加。                 在对象。 (控制器/ MainController.spec.js:28:36)     Chrome 55.0.2883(Windows 7 0.0.0):执行4 of 4(1次失败)(0.016秒/0.012秒)

          
        1. 此外,在describe('Main Controller', function () { var $controller, MainController, UserFactory; var data = { "name": "Shashank", "rank": "1" } beforeEach(angular.mock.module('app')); beforeEach(inject(function (_$controller_, _UserFactory_) { $controller = _$controller_; UserFactory = _UserFactory_; MainController = $controller('MainController', {UserFactory: UserFactory}); spyOn(MainController, 'add').and.callThrough(); spyOn(MainController, 'getHardData').and.callThrough(); })) it('should be defined', function () { expect(MainController).toBeDefined(); }) it('should have number = 3', function () { expect(MainController.number).toEqual(5) }) it('add() should assign value properly', function () { // expect(MainController.add).toHaveBeenCalled(); }) it('getHardData should assign the exact data', function () { // expect(MainController.getHardData).toHaveBeenCalled(); // expect(MainController.data).toEqual(data); }) }) 中,我了解到我们正在分配工厂的值,但将其更改为$controller('MainController', {UserFactory: UserFactory});并未引发任何错误。的 WHY吗
        2. 请帮助我理解我的愚蠢错误。

          了解业力和实践的最佳做法/示例的任何良好链接茉莉花会有很大的帮助

1 个答案:

答案 0 :(得分:1)

查看控制器,它会公开四个属性 - 两个是函数(如果计算sumVal函数中创建的add,则有五个属性)。

属性datanumber可以简单地断言它们在控制器创建后被正确初始化,就像你用其中一个一样。

对于add函数,最明显的测试是它应该添加两个参数并正确分配结果。由于该函数有两个参数,因此您可以添加许多其他测试。不带参数调用函数,用一个数字和一个字符串调用函数等。如果你想测试这通常取决于用例和你的测试策略。

getHardData函数不带任何参数,因此您要测试的是它使用UserFactory并正确分配结果。

如果取消注释代码,测试失败的原因仅仅是因为函数永远不会被调用。控制器初始化时,控制器中没有任何内容调用addgetHardData方法,并且测试中没有任何内容可以调用它们。

要进行测试,您必须这样做:

it('add() should assign value properly', function() {
  MainController.add();
  expect(MainController.add).toHaveBeenCalled();
});

然而,这是一项无用的测试,因为您没有测试任何自己的功能。

相反,你应该这样做:

it('add() should assign value properly', function() {

  expect(MainController.sumVal).toBeUndefined();

  MainController.add(5, 10);

  expect(MainController.sumVal).toBe(15);
});

您不需要监视正在测试的控制器方法,因为您将手动调用它们。

当你有一个调用另一个依赖项的控制器方法时,你想使用间谍,比如getHardData

您不希望在测试中使用UserFactory的实际实现,因此您可以使用间谍来中断调用并控制它返回的内容。

例如:

it('getHardData should assign the exact data', function() {

  // Set up the spy and the return value
  spyOn(UserFactory, 'getData').and.returnValue(data);

  // Call the method that you are testing
  MainController.getHardData();

  // Assert that the dependency was called
  expect(UserFactory.getData).toHaveBeenCalled();

  // Assert that the returned data was assigned correctly
  expect(MainController.data).toEqual(data);
});

另一种方法是创建一个模拟实现并在控制器中使用它:

var MainController,
  data = {
    name: "Shashank",
    rank: "1"
  },
  UserFactory = {
    getData: function() {
      return data;
    }
  };

beforeEach(function() {

  angular.mock.module('app');

  inject(function($controller) {

    MainController = $controller('MainController', {
      UserFactory: UserFactory
    });
  });
});

it('getHardData should assign the exact data', function() {

  // Set up the spy
  spyOn(UserFactory, 'getData').and.callThrough();

  // Call the method that you are testing
  MainController.getHardData();

  // Assert that the dependency was called
  expect(UserFactory.getData).toHaveBeenCalled();

  // Assert that the returned data was assigned correctly
  expect(MainController.data).toEqual(data);
});

请注意,间谍现在使用and.callThrough()而不是and.returnValue(data)。如果您不使用此调用,间谍将中断调用,并且不会使用您的模拟实现。

$controller('MainController', {});没有抛出任何错误的原因是因为当传递一个空对象作为第二个参数(或根本没有参数 - $controller('MainController'))时,将自动注入真正的依赖关系,和你现在一样。