I am trying to write unit tests for our small but soon to grow library of testcafe business functions - i.e. thos libraries which use the page files, to test any of the non-simple logic.
To this end I am trying to write my first unit test for this function entityTabs - which is an imported async module, ui is an imported non async module, accountAssignmentControls is a pagefile. Those functions mentioned by this. are defined further up in the module. t is a testcafe import.
Initially I want to stub out all the functions and test that statAccountAssignments is called once (After that I will be testing for various combinations of the data which is passed in, but I can't get beyond the first hurdle).
I UNIT tested our non Async headless test library, but
One of the developers added some units tests using chair, mocha and sinon - but these were for non async portions of the project (file handling mostly) so I can't get what he wrote to apply.
FUT
async assignAccounts(assignments) {
await entityTabs.startAccountAssignment();
ui.logWithTimeStamp('WAiting for Account assignment dialog to appear', 2);
await t
.expect(accountAssignmentControls.accountAssignmentHeader.innerText)
.contains('Account Assignment', 'Header contains Account Assignment');
ui.logWithTimeStamp('Header visible waiting for accounts list', 2);
await this.checkAccountList();
const assignmentsCount = assignments.length;
ui.logWithTimeStamp('Doing ' + assignmentsCount + ' assignments: ', 1);
for (let i=0; i<assignmentsCount; i++) {
ui.logWithTimeStamp(i + ': ' + JSON.stringify(assignments[i]), 1);
if (assignments[i].type === 'credit') {
await this.assignCreditAccount(assignments[i]);
} else if (assignments[i].type === 'debit') {
await this.assignDebitAccount(assignments[i]);
} else {
await this.assignFullAccount(assignments[i]);
}
ui.logWithTimeStamp('Assignment done', 3);
await t.takeScreenshot();
};
}
current failing test
import chai from 'chai';
import sinon from 'sinon';
import sinonChai from 'sinon-chai';
import AccountAssignment from '../../business-functions/account-assignment';
let accountAssignmentControls;
// let busyLoader;
let entityTabs;
let ui;
let t;
// Register the sinon-chai extensions.
chai.use(sinonChai);
const expect = chai.expect;
// We must turn off the no-invalid-this rule because of how mocha uses this to be the current test fixture.
/* eslint no-invalid-this: "off" */
describe('business-functions - Account assignment', function() {
describe('AccountAssignment class', function() {
describe('assignAccounts', function() {
let sandbox;
before(() => {
sandbox = sinon.sandbox.create();
});
after(() => {
sandbox.restore();
});
describe('when one of each assignment', function() {
it('starts assignment', async function() {
const fakeResponse = 'dont care';
const accountAssignment = new AccountAssignment();
t = sinon.stub();
entityTabs = sinon.stub();
ui = sinon.stub();
ui.logWithTimeStamp = sinon.stub();
accountAssignmentControls = sinon.stub();
// let f = sinon.fake();
let startAccountAssignment = sandbox
.stub(entityTabs, 'startAccountAssignment')
.resolves(fakeResponse);
// sandbox.stub(t, 'expect');
sandbox
.stub(accountAssignment, 'checkAccountList')
.resolves(fakeResponse);
sandbox
.stub(accountAssignment, 'assignCreditAccount')
.resolves(fakeResponse);
sandbox
.stub(accountAssignment, 'assignDebitAccount')
.resolves(fakeResponse);
sandbox
.stub(accountAssignment, 'assignFullAccount')
.resolves(fakeResponse);
sandbox
.stub(accountAssignmentControls, 'accountAssignmentHeader')
.resolves(fakeResponse);
sandbox
.stub(t, 'expect')
.resolves(fakeResponse);
sandbox
.stub(t, 'contains')
.resolves(fakeResponse);
sandbox
.stub(t, 'takeScreenshot')
.resolves(fakeResponse);
await accountAssignment.assignAccounts({});
expect(startAccountAssignment).to.be.callledOnce;
});
});
});
});
});
which when run gets
TypeError: Cannot stub non-existent own property startAccountAssignment at Sandbox.stub (node_modules\sinon\lib\sinon\sandbox.js:286:19) at Context._callee$ (C:/Projects/Platform/PlatformTesting/UITests-NotProtractor/unit-tests/business-functions/account-assignment.tests.js:49:14) at tryCatch (node_modules\regenerator-runtime\runtime.js:65:40) at Generator.invoke [as _invoke] (node_modules\regenerator-runtime\runtime.js:303:22) at Generator.prototype.(anonymous function) [as next] (node_modules\regenerator-runtime\runtime.js:117:21) at step (unit-tests\business-functions\account-assignment.tests.js:21:191) at C:\Projects\Platform\PlatformTesting\UITests-NotProtractor\unit-tests\business-functions\account-assignment.tests.js:21:437 at new Promise () at Context. (unit-tests\business-functions\account-assignment.tests.js:21:99)
Not related to this but for information - use prototype keyword for stubbing out the instance method
i-e sandbox.stub(deviceRegistryRepository.prototype, "getByName").resolve();
and for static method no need to use the prototype keyword
i-e sandbox.stub(myStaticClass.prototype, "getMyStaticMethod").resolve();
You are not stubbing out entityTabs
correctly, and the module you are testing is not using your stub.
To be more specific: you've declared a local var let entityTabs;
and then later assigned that var, entityTabs = sinon.stub();
. And finally you are attempting to stub out a method startAccountAssignment()
on that object, but it has no such property because it's not the actual entityTabs
module/object, and based on the code snippets you've included, it is not the one that the module you're testing will even use.
Depending on how the entityTabs
object is written (is it in it's own module? is that a singleton? is it a class?), you will need to import it, and stub out the method's you wish to mock, or you want to use something like proxyquire
to mock out entityTabs
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With