title: How to test handler with if/then blocks in a unit test for an Angular.js service?
body: <p>I am new to testing and I need to test the handler in my Angular.js service (Using Jasmine and Mocha). This service checks the url and redirects to a state <code>main.loadbalancer.readonly</code> if the device number is readonly.</p>
  
  <p>I am not sure how to test the handler, so since they are 2 if/then blocks with a function, I broke them up into their each <code>beforeEach(inject(function() {})</code>. Since they are going to be reused for several instances, I thought that would be best and then call them by <code>callHandler1(....)</code>, etc.</p>
  
  <p>Right now, I am getting:</p>
  
  <pre><code>readonly service paste url with device 55, first load, will not go to main state
      â ReferenceError: callHandler1 is not defined
  </code></pre>
  
  <p>Am I doing this correctly?</p>
  
  <hr>
  
  <p>Service:</p>
  
  <pre><code>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 &amp;&amp; toState.name !== "main" &amp;&amp; DeviceVal.lb.id === "undefined";
      };
      if (typeof DeviceVal.lb.id === "undefined" &amp;&amp; toState.name !== "main" || checkUrlDirectEdit()) {
        event.preventDefault();
        DeviceVal.previousDevice = device;
        $state.transitionTo("main", {}, {
          location: false
        });
      }
      if (DeviceVal.readonly &amp;&amp; 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();
      });
    });
  });
  </code></pre>
  
  <hr>
  
  <p>Test for service:</p>
  
  <pre><code>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 &amp;&amp; toState.name !== "main" &amp;&amp; DeviceVal.lb.id === "undefined";
      }
    }));
  
    beforeEach(inject(function() {
      function callHandler1(DeviceVal, toState, device) {
        if (typeof DeviceVal.lb.id === "undefined" &amp;&amp; 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 &amp;&amp; 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 });
      });
  });
  </code></pre>