I am stuck to do the Unit Test with Karma, I don't have idea how to the unit test because it's my first time. I am using AngularJS and the unit test is Karma.
The thing is this: I'm using a service to obtain the firstName, lastName and PhoneNumber of the customer to show in my form, and it works without any problem BUT, when I'm trying to do the unit test the error is always this:
directionFormulation component should load customer profile FAILED
TypeError: Cannot read property 'firstName' of undefined
directionFormulation.js
function directionFormulationController(event, customer, resolveLocation, order) {
this.$onInit = onInit;
this.input = this.input || {};
function onInit() {
loadCustomerData();
}
function loadCustomerData() {
this.input.firstName = order.customer.firstName;
this.input.lastName = order.customer.lastName;
this.input.phoneNumber = order.customer.phoneNumber;
}
}
})();
Unit test: directionFormulation.spec.js:
it('should load customer data', function () {
var emptyFirstName = { firstName: 'something'};
component.$onInit();
order.customer.firstName = { firstName: 'Something'};
order.customer.lastName = { lastName: 'Something' };
order.customer.phoneNumber = { phoneNumber: 55555555};
// component.input = {
// firstName: 'something',
// lastName: 'something',
// phoneNumber: 55555555
// };
component.loadCustomerData();
$rootScope.$apply();
component.input.firstName = newFirstName;
expect(component.input.firstName).to.be.equal({firstName: 'something'});
expect(component.input.lastName).to.be.not.empty;
expect(component.input.phoneNumber).to.be.null;
});
});
You are injecting order
into your controller, so you will need to "mock" out order
for your unit test:
describe('addressForm component', function () {
var component;
var scope;
var order;
beforeEach(function () {
bard.appModule('shopping.address');
bard.inject('$rootScope', '$componentController', '$q', 'resolveLocation', 'customer', 'event','order');
order = {
customer: {
firstName: 'Joe',
lastName: 'Smith',
phoneNumber: '416-555-1234'
}
};
scope = $rootScope.$new();
component = $componentController('addressForm', {
$scope: scope,
order: order
});
});
it('should be attached to the scope', function () {
expect(scope.addressForm).to.be.equal(component);
});
it('should load customer profile', function () {
component.$onInit();
component.loadCustomerProfile();
expect(component.input.firstName).to.be.equal(order.customer.firstName);
expect(component.input.lastName).to.be.equal(order.customer.lastName);
expect(component.input.phoneNumber).to.be.equal(order.customer.phoneNumber);
});
});
I'd like to highlight a few other issues:
Your first test asserting expect(scope.addressForm).to.be.equal(component);
is not going to pass. AddressFormController
is the name of your controller, and a controller is a property on a component.
I'm not sure what bard
refers to in your test and not sure whether appModule
is a property on your bard instance. Here is a sample of a component test set up of mine: https://gist.github.com/mcranston18/0ded29eca9a53efeb945736b0a053061
I would recommend this resource to learn a bit more about testing component controllers: http://www.codelord.net/2017/01/09/unit-testing-angular-components-with-%24componentcontroller/