AngularJS module for testing anonymous controller

I am trying to write tests for code that I did not write that uses ui-router .

I cannot figure out how to inject a controller into my test, as it is written internally and anonymously in the state configured on another controller:

$scope.deleteSomething = function() { $modal.open( templateUrl: '/delete-item-modal.html', controller: ['$scope', '$modalInstance', 'someService', function($scope, $modalInstance, someService) { .... } ], resolve: { ... } }); }; 

If the controller was called something like controller: 'TheController' , I would not have a problem with its injection by doing this in my test:

 beforeEach(inject(function($controller) { $controller('TheController', {/*dependancies to be injected*/}); })); 

But since the controller is anonymous, I do not have a descriptor and cannot figure out how to get it.

+5
source share
2 answers

This is an untenable situation. You must unit the code you are going to modify to protect against regressions. If you cannot unit test in the current state, then your only choice is to integrate it. Explain to the person requesting the job:

  • You must write tests for the code before modifying it.
  • Integration testing will take longer, but this is the only possible because of the code structure.
  • Refactoring by retrieving a named controller is a copy and a little risk.
  • A named controller can be easily tested.

What am I going to do.

0
source

You can test an anonymous controller. Instead of passing the controller identifier to the $controller(...) function, you need to pass the controller constructor array.

To do this, you need to make the controller code available for your unit test code. This is often done using a modulation tool for JavaScript (e.g. Webpack). But this can be done in the settings of your testing and <script></script> . I recommend using the tool.

Despite this, you get three files:

 // delete-item-controller.js DeleteItemController = ['$scope', '$modalInstance', 'someService', function($scope, $modalInstance, someService) { .... } ]; 

 // state-controller.js $scope.deleteSomething = function() { $modal.open( templateUrl: '/delete-item-modal.html', controller: DeleteItemController, resolve: { ... } }); }; 

 // delete-item-controller.spec.js beforeEach(inject(function($controller) { $controller(DeleteItemController, {/*dependancies to be injected*/}); })); 

Alternative example using a module loader

Using Webpack would look a little different ... but it eliminates the fuzzy, implied global object that holds onto DeleteItemController .

 // delete-item-controller.js module.exports = ['$scope', '$modalInstance', 'someService', function($scope, $modalInstance, someService) { .... } ]; 

 // state-controller.js var DeleteItemController = require("./delete-item-controller"); $scope.deleteSomething = function() { $modal.open( templateUrl: '/delete-item-modal.html', controller: DeleteItemController, resolve: { ... } }); }; 

 // delete-item-controller.spec.js var DeleteItemController = require("./delete-item-controller"); beforeEach(inject(function($controller) { $controller(DeleteItemController, {/*dependancies to be injected*/}); })); 
0
source

Source: https://habr.com/ru/post/1205447/


All Articles