Dave Mackintosh
Dave Mackintosh

Reputation: 2796

Karma testing a lot of files similar in structure automatically

So I have a folder full of scripts that all resemble a structure like this

// Adapter-100.js
angular.module('myModule', ['myParentFactory', function(myParentFactory) {
  return angular.extend(myParentFactory, {
    "someFunctionA" : function() {},
    "someFunctionB" : function() {},
    "someFunctionC" : function() {}
  });
}]);

And my test just checks that they have these three methods, trouble is there is about 100 of these files (they're adapters for communicating with a server)

Here is a representation of my tests file

// api-adapter-tests.js
describe('Unit: EndPointMethods', function() {

  var values, factory, adapter;

  // Boot the module
  beforeEach(function() {
    module('myModule');

    inject(function ($injector) {
      values  = $injector.get('AppConsts');
      factory = $injector.get('EndPointConnection');
      adapter = $injector.get('TestAdapter'); // This needs to change to match what adapter is being tested
    });
  });

  // Run some tests
  describe('AppConsts', function() {
    it('Should have an api_host key', function() {
      expect(values).toBeDefined();
      expect(values.api_host).toBeDefined();
      expect(typeof values.api_host).toBe('string');
    });
  });

  // Is this able to be generated to test each adapter independently?
  describe('TestEndPointMethod has minimum functional definitions', function() {
    it('should have 3 defined functions', function() {
      expect(factory.consumeResponse).toBeDefined();
      expect(factory.getEndPoint).toBeDefined();
      expect(factory.mutator).toBeDefined();
    });
  });
});

I don't want to have to write a separate describes/it block for each adapter but rather have Karma loop over all of these and create the tests on the fly (the tests are very unlikely to ever change)

I've Googled around for a solution to this but can't seem to find anything that does this kind of thing for me.

Upvotes: 0

Views: 139

Answers (1)

MarcoL
MarcoL

Reputation: 9989

You can wrap your suites in a clojure and pass the Adapter you want to test: mocha will take care of running it in the right way - and so Karma.

function runSuiteFor(newAdapter){
  return function(){
    // api-adapter-tests.js
    describe('Unit: EndPointMethods', function() {

      var values, factory, adapter;

      // Boot the module
      beforeEach(function() {
        module('myModule');

        inject(function ($injector) {
          values  = $injector.get('AppConsts');
          factory = $injector.get('EndPointConnection');
          adapter = $injector.get(newAdapter); // set the Adapter here
        });
      });

      // Run some tests
      describe('AppConsts', function() {
        it('Should have an api_host key', function() {
          expect(values).toBeDefined();
          expect(values.api_host).toBeDefined();
          expect(typeof values.api_host).toBe('string');
        });
      });

      // Is this able to be generated to test each adapter independently?
      describe('TestEndPointMethod has minimum functional definitions', function() {
        it('should have 3 defined functions', function() {
          expect(factory.consumeResponse).toBeDefined();
          expect(factory.getEndPoint).toBeDefined();
          expect(factory.mutator).toBeDefined();
        });
      });
    });
    } 
   }

   var adapters = ['MyTestAdapter1', 'MyTestAdapter2', etc...];

   for( var i=0; i<adapters.length; i++){
     runSuiteFor(adapters[i])();
   }

Note: IE8 has some issues with this approach sometimes, so in case you're with Angular 1.2 bare in mind this.

Upvotes: 1

Related Questions