Trying to test angular services with Jest and got this error:
[$injector:nomod] Module 'superag' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
How do I mock my module 'superag' and make available to mathService?
Do I have to import the app.js file with the module declaration every test I make?
Ps.: I've tried with beforeEach(module('superag')) too without success
package.json
"jest": {
"collectCoverageFrom": [
"**/*.{js}",
"!**/node_modules/**"
]
},
"devDependencies": {
"angular-mocks": "^1.6.9",
"jest-cli": "^23.0.0-alpha.0"
},
"dependencies": {
"angular": "^1.6.9"
}
}
math.service.js
function MathService(){
var addTwoNumbers = function(x, y){
return x + y;
};
return {
addTwoNumbers
};
}
angular.module('superag').factory('mathservice', MathService);
math.service.test.js
require('angular');
require('angular-mocks');
require('./math.service.js');
describe('Math service - addTwoNumbers', () => {
beforeEach(
angular.mock.module('superag')
);
var _mathservice;
beforeEach(inject((mathservice) => {
_mathservice = mathservice;
}));
it('1 + 1 should equal 2', () => {
var actual = _mathservice.addTwoNumbers(1,1);
expect(actual).toEqual(2);
});
});
This error occurs when you declare a dependency on a module that isn't defined anywhere or hasn't been loaded in the current browser context.
When you receive this error, check that the name of the module in question is correct and that the file in which this module is defined has been loaded (either via <script> tag, loader like require.js, or testing harness like karma).
A less common reason for this error is trying to "re-open" a module that has not yet been defined.
To define a new module, call angular.module with a name and an array of dependent modules, like so:
// When defining a module with no module dependencies,
// the array of dependencies should be defined and empty.
var myApp = angular.module('myApp', []);
To retrieve a reference to the same module for further configuration, call angular.module without the array argument.
var myApp = angular.module('myApp');
Calling angular.module without the array of dependencies when the module has not yet been defined causes this error to be thrown. To fix it, define your module with a name and an empty array, as in the first example above.
You need to load the module under test using the module function provided in angular-mocks, so it is available in your tests, per docs.
beforeEach(module('superag'))
Then you can inject in your service.
Related
I got a problem with execution order of generated javascript when bundling.
I'm getting this error when I bundle it all together.
Uncaught Error: [$injector:nomod] Module 'app.demo' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
I believe I've narrowed it down to angular.module("app.demo").service() being called before angular.module("app.demo", []) in the combined appbundle.js.
I've setup bundling like so. In visual studio 2013.
My folder structure is as follows:
I include it like so in my index.html.
<script src="App/appbundle.js"></script>
The relevant typescript files:
app.module.ts
module App {
"use strict";
// Create the module and define its dependencies.
angular.module("app", [
// Angular modules
"app.core",
"app.demo",
"app.services"
]);
}
demo.service.ts
module App.Services {
"use strict";
export interface IDemoService {
getData: () => Array<string>;
}
class demoService implements IDemoService {
static $inject: string[] = ["$http"];
constructor(private $http: ng.IHttpService) {
}
getData(): Array<string> {
return ["one", "two", "three"];
}
}
angular.module("app.services").service("demoService", demoService);
}
services.module.ts
module App.Services {
"use strict";
// Create the module and define its dependencies.
angular.module("app.services", []);
}
As stated earlier. I believe the problem comes from the order in which the files are combined into the appbundle.js.
So my question is. How do I fix this while keeping the bundling feature?
I realize that renaming the files would change the order they're included. But that's not something I'm willing to do :)
How do I fix this while keeping the bundling feature?
Use an external bundler e.g. webpack.
More : https://github.com/TypeStrong/atom-typescript/blob/master/docs/out.md
My code is like this
App.js
angular.module('mailerApp', [
'mailerApp.services',
'mailerApp.controllers',
'ui.bootstrap',
'angular-loading-bar',
'textAngular',
'angularFileUpload'
]);
Cotrollers.js
angular.module('mailerApp.controllers').controller('MailerCntrl', ['$scope', 'FileUploader', function ($scope, FileUploader) {
}]);
Services.JS
angular.module('mailerApp.services', []).factory('rateRequestService', ['$http', rateRequestService]);
function rateRequestService($http) {
var service = { getData: getData };
return service;
function getData() {
return $http({
method: 'Get',
url: '../services/RateRequestWS.asmx/GetReadOnlyData?'
});
}
}
HTML
body ng-app="mailerApp" ng-controller="MailerCntrl">
</body>
Everything looks okay to me, But this throws an error
Uncaught Error: [$injector:nomod] Module 'mailerApp.controllers' is not available! You either misspelled the module name or forgot to
load it. If registering a module ensure that you specify the
dependencies as the second argument.
Can any one point out What I am doing wrong here?
Instead of
angular.module('mailerApp.controllers').controller...
You need to do
angular.module('mailerApp').controller... // to add the controller to the mailerApp module
angular.module('mailerApp.controllers', []).controller... // to add the controller to a new mailerApp.controllers module
And the same goes with;
angular.module('mailerApp.services').factory...
Instead you need to
angular.module('mailerApp').factory... // add the factory to the mailerApp module
angular.module('mailerApp.services', []).factory... // add the factory to a new mailerApp.services module
When you create and angular module, you give it a name and the list of dependencies in the array;
var module = angular.module('<module_name>', [<dependencies>])
But then when you add a controller/factory to the module, you'll need to either use the module object you created.
when you write angular.module('mailerApp.controllers', [ ]), you create new module as 'mailerApp.controllers' and in second parameter you pass dependencies.
and when you write angular.module('mailerApp.controllers') it references previously created module.
But in your case your directly referencing module without creating it, therefore it gives you error for that. Same goes for other cases
I'm trying to create some unit tests in Angular using Jasmine being run through Teaspoon. The tests are running, however I have a simple test just to test the existence of a controller that is failing. I have the following test setup.
//= require spec_helper
require("angular");
require("angular-mocks");
var app = require("./app");
describe("My App", function() {
describe("App Controllers", function() {
beforeEach(module("app"))
it("Should have created an application controller", inject(function($rootScope, $controller){
var scope = $rootScope.$new();
ctrl = $controller("ApplicationCtrl", { $scope: scope });
}));
})
})
The require statements are processed by Browserify which is handling my dependencies, but I can also hook into sprockets which I'm using for the spec helper.
Inside the app that is being required, I have
require("angular");
var controllers = require("./controllers");
var app = angular.module("app", [
"app.controllers"
]);
exports.app = app;
When I run this test, I get the following error produced
Failure/Error: TypeError: '[object Object]' is not a function (evaluating 'module("aialerts")')
I've spent quite a while trying to figure this out but I have no idea what's going on. Any help appreciated.
I had the same problem. Change this line:
beforeEach(module("app"))
to:
beforeEach(angular.mock.module("app"))
Browserify uses Node-style require, where module is an object that you can use to export functionality:
console.log(module); // {exports: {}}
angular-mocks.js tries to attach a function to window.module, but that's not possible in Browserify/Node.
Taking a look through the angular-mocks source, it appears that angular-mocks also attaches the module function to angular.mock. So instead of using the global module object, you must use angular.mock.module.
I have problems with call a factory in one module from another module. I am using angular.js + require.js.
Here is my code
Module 1:
define(['angular', 'app/admin/app.admin', 'app/admin/account/services'], function (angular, app, services) {
app.controller('MainCtrl', ['$scope', 'providerService', function ($scope, providerService) {
$scope.showMe = false;
$scope.provider = providerService.Providers;
}]);
return app;
});
Module 2
define(['angular', 'app/admin/config/index'], function (angular) {
'use strict';
var service = angular.module('app.admin.account.services', []);
service.factory('providerService', ['app.admin.config',
function (config) {
var providers = [
{ name: 'google+', url: config.AUTH_URL + '/google' },
{ name: 'facebook', url: config.AUTH_URL + '/facebook' }
];
return {
Providers: providers
};
}
]);
return service;
});
When i try to call providerService in module 2 from module 1. I got an error say providerService is not there. Can someone tell me what I did wrong here?
Cheers
It is perfectly fine to use RequireJS and AngularJS together, however the term "module" has different meaning between the two and is a little bit confusing when it comes to dependencies.
In RequireJS a "module" is a typical Javascript file that encapsulates a piece of code. You define the dependencies using RequireJS in order to pass in/around other modules as dependencies and ensure correct script load ordering.
In AngularJS the term "module" specifically means an AngularJS "module", which is a container for a number of controller/services/directive etc. declarations.
You use RequireJS to define the order and dependencies of your script files. You then also need to tell Angular which "Angular modules" your module depends on, essentially importing all of the controllers/services/directives along with it.
In 'app/admin/app.admin' make sure you define the dependencies for your AngularJS module by passing in the 'app.admin.account.services' module as a second parameter e.g.
var app = angular.module('app.admin', ['app.admin.account.services']);
That will then import the 'app.admin.account.services' module into your main module making your providerService available for dependency injection.
I have defined a empty module in angular.js:
angular.module('todoList', [], function () {
})
then I want test it, in my conf.js, I load these javascript:
files = [
JASMINE,
JASMINE_ADAPTER,
// lib
'../js/lib/angular.min.js',
'../js/lib/jquery-1.9.1.min.js',
// our app
'../js/project.js',
// test file
"test/*.js"
];
Then I want test it in test file:
describe('My own function', function(){
beforeEach(module('todoList'));
});
but this step tell me
FAILED My own function encountered a declaration exception
I don't understand why just a load module sentence would cause wrong
How can I fix this problem?
Try including angular-mocks.js in your config file.