in my test/features/support/world.js
module.exports = function(){
var PersistenceWorld = function PersistenceWorld(callback){
this.cleanUp(callback);
};
PersistenceWorld.prototype.addNewReciepe = function(callback){
};
PersistenceWorld.prototype.cleanUp = function(callback){
};
};
and My test/features/step_definitions/first_steps
module.exports = function(){
this.World = require('../support/world');
console.log(this);
this.Before(function (callback) {
console.log("hey I run before each scenario");
callback();
});
this.After(function (callback) {
console.log("hey I run after each scenario");
callback();
});
this.Given(/^user is on homepage$/, function(callback) {
callback.pending();
});
};
when I donot require the world before after is getting fired.
MyApp
.sass-cache
.tmp
app
bower_components
ember-mocha-adapter
node_modules
test
features //I added this folder for cucumberjs features.
step_definitions //I added
lib
mocha
chai.js
expect.js
spec
Related
when I execute Jest in Javascript test with AWS mock via npm, it will be Failure.
because I use singleton class.
The difference like here.
「module.exports = Users;」 or 「module.exports = new Users();」
I guess AWS mock doesn't work with singleton class.
in that cause, how should I do to solve this problem?
'use strick';
var aws = require('aws-sdk')
aws.config.update({region:'ap-northeast-1'})
class Users {
constructor() {
this.table = 'Users'
this.dynamodb = new aws.DynamoDB()
}
getData(email) {
let params = {
TableName: this.table,
Key : { 'email': {'S':email} }
}
return this.dynamodb.getItem(params).promise()
}
}
// module.exports = Users // ← this will be success.
module.exports = new Users(); // ← this will be failure.
'use strict';
var aws = require('aws-sdk-mock'),
users = require('./user'),
chai = require('chai'),
path = require('path'),
should = chai.should(),
input = 'test#gmail.com',
usersObj;
aws.setSDK(path.resolve('node_modules/aws-sdk'));
describe('All Tests', function () {
// this.timeout(0);
beforeEach(function () {
aws.mock('DynamoDB', 'getItem', function (params, callback) {
callback(null, {Item: {email: params.Key.email.S}});
});
// usersObj = new users(); ← this will be success.
usersObj = users; // ← this will be failure.
});
it('getData', function (done) {
usersObj.getData(input).then(function (res) {
console.log(res);
res.Item.email.should.equal(input);
done();
});
});
});
This line:
module.exports = new Users();
...means that a Users object will get created as soon as the code runs...and it runs as soon as user.js is required.
This line:
users = require('./user')
...is at the top of your test file and this line:
aws.mock('DynamoDB', 'getItem', function (params, callback) {
callback(null, {Item: {email: params.Key.email.S}});
});
...is in a beforeEach...
...which means that user.js is required and runs before the mock has been created...which causes the test to fail.
If you are going to export an instance of Users then you just need to make sure you don't require the user.js file in your test until after you have set up your mock:
var aws = require('aws-sdk-mock'),
chai = require('chai'),
path = require('path'),
input = 'test#gmail.com',
usersObj;
chai.should()
aws.setSDK(path.resolve('node_modules/aws-sdk'));
describe('All Tests', function () {
beforeEach(function () {
aws.mock('DynamoDB', 'getItem', function (params, callback) {
callback(null, { Item: { email: params.Key.email.S } });
}); // <= set up the mock first...
usersObj = require('./user'); // <= ...then require user.js
});
it('getData', function (done) {
usersObj.getData(input).then(function (res) {
res.Item.email.should.equal(input); // Success!
done();
});
});
});
I could resolve this pattern too.
'use strict';
var aws = require('aws-sdk-mock'),
users = require('./user'),
chai = require('chai'),
path = require('path'),
should = chai.should(),
input = 'test#gmail.com',
usersObj;
const awsObject = require('aws-sdk');
aws.setSDK(path.resolve('node_modules/aws-sdk'));
describe('All Tests', function () {
// this.timeout(0);
beforeEach(function () {
aws.mock('DynamoDB', 'getItem', function (params, callback) {
callback(null, {Item: {email: params.Key.email.S}});
});
// it will be resolve problem by creating new AWS instance.
users.dynamodb = new awsObject.DynamoDB();
});
it('getData', function (done) {
users.getData(input).then(function (res) {
console.log(res);
res.Item.email.should.equal(input);
done();
});
});
});
You must call the aws client inside the class constructor
class MyClass {
constructor(){
this.dynamodb = new DynamoDB.DocumentClient({ region: "us-west-2" });
}
...
In the test file you must create a new instance of your class just after call de AWSMock. Example:
it('Should save on dinamoDB with param atributes void()', async () => {
AWSMock.mock('DynamoDB.DocumentClient', 'update', function (params, callback){
callback(null, { Attributes: { currentValue: 1 } } );
});
AWSMock.mock('DynamoDB.DocumentClient', 'put', function (params, callback){
callback(null, true);
});
const myClass = new MyClass();
...
I want to write a unit test for a route's method.
routes/tickets
addTicketUserAssoc(ticket, ticketUserAssoc) {
let copy = ticketUserAssoc.copy();
copy.set('ticket', ticket);
ticketUserAssoc.reset();
},
It uses copy and reset on an ember-data record. They are methods which are added during initialization.
initializers/model
export default {
name: 'model',
initialize: function() {
if (alreadyRun) {
return;
} else {
alreadyRun = true;
}
DS.Model.reopen(isValidated, {
copy: function(options){
// some code ...
},
reset() {
// some code ...
}
});
}
};
If I try to import the initializer to the unit test, it does not even appears on the qunit's module list.
Solution
I ended up doing this:
moduleFor('route:tickets', 'Unit | Route | tickets', {
// Specify the other units that are required for this test.
needs: [
// ...
],
beforeEach() {
Ember.run(function() {
application = Ember.Application.create();
application.deferReadiness();
});
}
});
test('assign ticket', function(assert){
let route = this.subject();
let store = route.get('store');
ModelInitializer.initialize(application);
// ...
})
So I have the following GulpJS tasks that are all related with installing and copying bower files:
gulp.task('bower-install', function() {
var command = 'bower install';
gutil.log(gutil.colors.cyan('running command:'), command);
return gulp.src('', {read: false})
.pipe(shell([
command
]));
});
gulp.task('bower-copy', function() {
return gulp.src(gulpConfig.bowerCopy.map(function(item) {
return './bower_components/' + item;
}), {base: './bower_components'})
.pipe(gulp.dest('./htdocs/components'));
});
gulp.task('bower-copy-clean', function() {
return gulp.src('./bower_components')
.pipe(clean());
});
gulp.task('bower-clean', function() {
return gulp.src('./htdocs/components')
.pipe(clean());
});
gulp.task('bower', 'Download and move bower packages', function(done) {
runSequence(
'bower-install',
'bower-clean',
'bower-copy',
'bower-copy-clean',
done
);
});
I am doing it this way because I need these tasks to run sequentially one after the other. While when I run gulp bower everything works as expected, I would like to structure this code so that the only exposed task is bower as all the bower-* are pointless to run by themselves.
Is there any way to write this code so all the bower-* task run one after the other but only expose the bower task?
Because a gulpfile is just a regular node app, usually when we get into stuck situations like this, it's good to ask "what would we do if we didn't have gulp?" Here's my solution:
var async = require('async');
var del = require('del');
var spawn = require('child_process').spawn;
function bowerInstall(cb) {
var command = 'bower install';
gutil.log(gutil.colors.cyan('running command:'), command);
var childProcess = spawn('bower', ['install'], {
cwd: process.cwd(),
stdio: 'inherit'
}).on('close', cb);
});
function bowerCopy(cb) {
gulp.src(gulpConfig.bowerCopy.map(function(item) {
return './bower_components/' + item;
}), {base: './bower_components'})
.pipe(gulp.dest('./htdocs/components'))
.on('end', cb);
});
function bowerCopyClean(cb) {
del('./bower_components', cb);
});
function bowerClean() {
del('./htdocs/components', cb);
});
gulp.task('bower', 'Download and move bower packages', function(done) {
async.series([
bowerInstall,
bowerClean,
bowerCopy,
bowerCopyClean
], done);
});
Note that I also sped up your build substantially by not reading in the entirety of the bower_components and htdocs/components directories into ram.
I'm pretty new to angular and been wanting to test drive and I've hit a snag mocking out $window. The item in which I'm attempting to test is very simple but important -- I need to know if localStorage is there or not and need to be able to fake out $window to do so.
The code is very basic so far and what I have is this for the service ...
'use strict';
mainApp.factory('somedataStorage',function($window) {
var local = $window.localStorage;
return {
hasLocal: function() {
return local != undefined;
},
};
});
How I'm testing it is this ...
(function () {
var fakeWin = {
localStorage: null
};
var $injector = angular.injector(['ngMock', 'ng', 'mainApp']);
//var $window = $injector.get('$window');
var init = {
setup: function () {
//this.$window = fakeWin;
},
}
module('LocalStorageTests', init);
test("if localstorage isn't there, say so", function () {
var $service = $injector.get('somedataStorage' /*, {$window: fakeWin} */);
ok(!$service.hasLocal, "no local storage");
});
})();
So what am I missing?
I started to write unit tests for my angular app.
However it seems to me that I use a lot of boilerplate code to init and test the controller.
In this Unit Test I want to test if a model from the scope is sent to the Api when I execute a function.
I needed 20 lines of code for this. This makes it inconvenient to write unit tests that do only one thing.
Do you have any tips on getting the code size to a smaller chunk?
This is my current unit test:
'use strict';
describe('controllers', function(){
beforeEach(module('kronos'));
describe('CustomerSignupCtrl', function() {
it('should send customer to Api on submit', inject(function($controller) {
var scope = {};
var $location = {};
var Api = {
signupCustomer: function(customer) {
expect(customer).toEqual({attrs: "customerdata"});
return {
success: function() { return this; },
error: function() { return this; }
};
}
};
var ctrl = $controller('CustomerSignupCtrl', {
$scope: scope,
$location: location,
Api: Api});
scope.customer = {attrs: "customerdata"};
scope.signup();
}));
});
});
What I don't like in particular are the following points
I need to init the all dependencies and it doesn't matter if I use them or not
The Api returns a promise that I only need because the controller is expecting the promise
I need to init the controller.
How can I make this code shorter and more explicit?
Edit: I just noticed I can ignore the $location Service for this unit test. Great
Edit2: I found out about angular-app, which serves as a good practice example app. There you can find specs with jasmine, which are really nice written.
Use another beforeEach method in your describe scope to set up scope, $location, controller etc, then just change them in your test as you need to. Js is dynamic so all should be fine.
You can also extract each object that you set up into a function so that you can reinitialise them in a test if you need to.
describe('controllers', function(){
beforeEach(module('kronos'));
describe('CustomerSignupCtrl', function() {
var controller, scope, $location, Api;
beforeEach(function(){
scope = {};
$location = {};
Api = {
signupCustomer: function(customer) {
expect(customer).toEqual({attrs: "customerdata"});
return {
success: function() { return this; },
error: function() { return this; }
};
}
};
controller = makeController();
})
function makeController(){
inject(function($controller){
controller = $controller('CustomerSignupCtrl', {
$scope: scope,
$location: location,
Api: Api});
});
}
it('should send customer to Api on submit', function() {
scope.customer = {attrs: "customerdata"};
scope.signup();
});
});
});
You can not shorten your code much. Things like initialization, mocking and assertion have to be done at some place. But you can improve the readability of your code by decoupling initialization and test code. Something like this:
describe('CustomerSignupCtrl', function(){
var controller, scope, location, api;
beforeEach(module('kronos'));
// initialization
beforeEach(inject(function($controller, $rootScope, $location, Api){
scope = $rootScope.$new();
location = $location;
api = Api;
controller = $controller('CustomerSignupCtrl', {
$scope: scope, $location: location, Api: api});
}));
// test
it('should send customer to Api on submit', function() {
scope.customer = {attrs: "customerdata"};
spyOn(api,'signupCustomer').andCallFake(function(customer) {
return {
success: function() { return this; },
error: function() { return this; }
};
});
scope.signup();
expect(api.signupCustomer).toHaveBeenCalledWith(scope.customer);
});
});