如何在Angular.js服务的单元测试中使用if / then块测试处理程序?

时间:2014-10-13 00:48:56

标签: angularjs unit-testing jasmine

我是测试的新手,我需要在Angular.js服务中测试处理程序(使用Jasmine和Mocha)。如果设备编号是只读的,此服务会检查网址并重定向到状态main.loadbalancer.readonly

我不确定如何测试处理程序,所以因为它们是2 if / then阻止了一个函数,所以我把它们分成了每个beforeEach(inject(function() {})。由于它们将在几个实例中被重用,我认为这将是最好的,然后通过callHandler1(....)等来调用它们。

现在,我得到了:

readonly service paste url with device 55, first load, will not go to main state
    â ReferenceError: callHandler1 is not defined

我这样做是否正确?


服务:

angular.module("main.loadbalancer").run(function($rootScope, $state, DeviceVal) {
  return $rootScope.$on("$stateChangeStart", function(event, toState) {
    var checkUrlDirectEdit, device;
    device = window.location.hash.split("/")[2];
    checkUrlDirectEdit = function() {
      return DeviceVal.previousDevice !== device && toState.name !== "main" && DeviceVal.lb.id === "undefined";
    };
    if (typeof DeviceVal.lb.id === "undefined" && toState.name !== "main" || checkUrlDirectEdit()) {
      event.preventDefault();
      DeviceVal.previousDevice = device;
      $state.transitionTo("main", {}, {
        location: false
      });
    }
    if (DeviceVal.readonly && toState.name !== "main.loadbalancer.readonly") {
      event.preventDefault();
      $state.transitionTo("main.loadbalancer.readonly", {
        id: DeviceVal.lb.id
      }, {
        location: true,
        reload: true
      });
    }
    return window.addEventListener("hashchange", function() {
      return location.reload();
    });
  });
});

服务测试:

describe("readonly service", function() {

  beforeEach(function() {
    return module("main");
  });

  beforeEach(inject(function($rootScope, _$state_, _DeviceVal_) {
    $rootScope = $rootScope;
    $state = _$state_;
    DeviceVal = _DeviceVal_;
    spyOn($state, "transitionTo");
    spyOn($rootScope, "$broadcast");
    event = jasmine.createSpyObj("event", ["preventDefault"]);
    event.preventDefault();
  }));

  beforeEach(inject(function() {
    checkUrlDirectEdit = function(DeviceVal, toState) {
      return DeviceVal.previousDevice !== device && toState.name !== "main" && DeviceVal.lb.id === "undefined";
    }
  }));

  beforeEach(inject(function() {
    function callHandler1(DeviceVal, toState, device) {
      if (typeof DeviceVal.lb.id === "undefined" && toState.name !== "main" || checkUrlDirectEdit()) {
        event.preventDefault();
        DeviceVal.previousDevice = device;
        $state.transitionTo("main", {}, {
          location: false
        });
      }
    }
  }));

  beforeEach(inject(function() {
    function callHandler2(DeviceVal, toState, device) {
      if (DeviceVal.readonly && toState.name !== "main.loadbalancer.readonly") {
        event.preventDefault();
        $state.transitionTo("main.loadbalancer.readonly", {
          id: DeviceVal.lb.id
        }, {
          location: true,
          reload: true
        });
      }
    }
  }));

  it("paste url with device 55, first load, will not go to main state", function() {
    device = 55;
    DeviceVal.lb.id = undefined;
    toState = { name: "not main" },
    DeviceVal.previousDevice = undefined;
    DeviceVal.readonly = false;
    callHandler1(DeviceVal, toState, device);
    callHandler2(DeviceVal, toState, device)
    expect(event.preventDefault).toBeDefined();
  });

  it("paste url with device 56, first load, will go to main state", function() {
    device = 56;
    Device.lb.id = undefined;
    toState = { name: "not main" },
    DeviceVal.previousDevice = undefined;
    DeviceVal.readonly = true;
    callHandler1(DeviceVal, toState, device);
    callHandler2(DeviceVal, toState, device)
    expect(event.preventDefault).toHaveBeenCalled();
    expect($state.transitionTo).toHaveBeenCalledWith("main.loadbalancer.readonly",
      { id: 55 }, 
      { location: true, reload: true });
    });
});

0 个答案:

没有答案