Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@demisx
Last active January 28, 2018 03:56
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save demisx/10b4c90fc675014eefe3 to your computer and use it in GitHub Desktop.
Save demisx/10b4c90fc675014eefe3 to your computer and use it in GitHub Desktop.
AngularJS 1.x Unit Testing with Mocha/Chai/Chai-as-promised

UI States

describe('state', function() {
  var stateName ='app.classified';
  var $state;
  var h;

  beforeEach(function() {
    module('unitTestTemplates');
    module('helpers.unit.state');
    module('states.app');
    module('states.app.classified', function($provide) {
      $provide.value('Classified', {
        get: sinon.stub().returns('something')
      });
    });

    inject(function(_$state_, _stateTestHelpers_) {
      $state = _$state_;
      h = _stateTestHelpers_;
    });
  });

  context(stateName, function() {
    it('resolves classified property', function() {
      expect(h.resolve('classified').forStateAndView(stateName))
        .to.eql('something');
    });

    it('maps to correct state URL', function() {
        expect($state.href(stateName, { classifiedId: 1 }))
          .to.eql('#/classifieds/1');
    });

    it('is activated when visiting state URL', function () {
      h.goToUrl('classifieds/1');
      expect($state.current.name).to.eql(stateName);
    });
  });

  context('title@app view', function() {
    it('controller defines `classified` instance property', function() {
      ctrlFn = h.getController().forStateAndView(stateName, 'title@app');
      expect(new ctrlFn({}, $state)).to.have.ownProperty('classified');
    });

    it('changeClassified() transitions state to another classified', function() {
      $state.go = sinon.spy();
      ctrlFn = h.getController().forStateAndView(stateName, 'title@app');
      ctrl = new ctrlFn({}, $state);
      ctrl.classified.current.id = 1;

      ctrl.changeClassified();
      expect($state.go).calledWith(stateName, { classifiedId: 1 });
    });
  });
});

Application controllers

describe('ViewAdDetailController', function() {
 it('does something', function() {
 ...
 });
}

Services

escribe('pageMetaService', function() {
  var pageMetaService;
  var stateMock;

  beforeEach(function() {
    stateMock = {
      current: {
        name: '',
        data: {
          doc: {
           htmlTitle: ''
          }
        }
      }
    };

    module('components.pageMeta', function($provide) {
      $provide.value('$state', stateMock);
    });

    inject(function(_pageMetaService_) {
      pageMetaService = _pageMetaService_;
    });
  });

  describe('htmlTitle()', function() {
    it('returns page html title when present', function() {
      var htmlTitle = "Some html title";

      stateMock.current.data.doc.htmlTitle = htmlTitle;
      expect(pageMetaService.htmlTitle()).to.eql(htmlTitle);
    });

    it('returns empty string when html title is undefined', function() {
      delete stateMock.current.data.doc.htmlTitle;
      expect(pageMetaService.htmlTitle()).to.eql('');
    });
  });

  describe('bodyId()', function() {
    it('returns bodyId add hyphenated state name', function() {
      stateMock.current.name = 'app.area.list';
      expect(pageMetaService.bodyId()).to.eql('app-area-list');
    });

    it('returns empty string when state name is undefined', function() {
      delete stateMock.current.name;
      expect(pageMetaService.bodyId()).to.eql('');
    });
  });
});

States

Models

Directives

Test directive controllers used with BindToController option angular/angular.js#9425 (comment)

var opts = { call: function (msg) { console.log(msg); } };
var mock = sinon.mock(opts);
// You state your success criteria upfront
mock.expects("call").once().withExactArgs("Hello World");
/* ... twice, atMost, never, exactly, on, etc ... */
opts.call("Hello World");
mock.verify();
mock.restore();
// Sinon spy function
var callback = sinon.spy();
callback();
callback.called;
callback.callCount;
callback.calledWith(arg1);
callback.threw();
callback.returned(obj);
callback.calledBefore(spy);
callback.calledAfter(spy);
// Sinon spy method
sinon.spy($, "ajax");
$.ajax({ / ... / });
var call = $.ajax.getCall(0);
call.args;
call.exception;
call.returnValue;
$.ajax.restore();
var stub = sinon.stub();
var opts = { call: function (msg) { console.log(msg); } };
// We can control how the sinon.stub() will behave based on how it’s called!
stub.withArgs("Hello").returns("World");
stub.withArgs("Wuz").returns("Zup?");
stub.withArgs("Kapow").throws();
stub.withArgs(opts).yieldsTo("call", ["Howdy"]);
stub("Hello"); // "World"
stub(opts); // "Howdy"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment