I've been searching the web for a while and I've yet to find the answer to this.
Let's say we're testing the following:
function p() {
return Promise.resolve(1);
}
class Sample {
constructor() {
this.stuff = 2;
}
sample () {
p().then((data) => {
this.stuff = data;
});
//more stuff
}
}
module.exports = {Sample};
How could we check that, eventually this.stuff
is populated without returning said promise?
This is what I've been able to do until now:
let expect = require('chai').expect;
let sinon = require('sinon');
let Sample = require('./source.js').Sample;
describe('stuff', function () {
it('test2', function() {
let sample = new Sample();
return Promise.resolve(sample.sample())
.then(() => {
expect(sample.stuff).to.be.eql(2);
});
});
});
In which, each then
gets the next tick (if we had multiple then
s in our sample we'd also need multiple then
s in our test).
(And before you say process.nextTick
, I want this to run in the browser with karma-mocha)
Thanks in advance!
This could be easily tested if the code was restructured, to support testability.
One way to do this would be to take an optional p
interface for the object instantiation. The value could default to your defined p
but would allow for a test to create a fake object and verify that your Sample
operates on it correctly.
function p() {
return Promise.resolve(1);
}
class Sample {
constructor(pFn) {
this.stuff = 2;
this.p = pFn || p;
}
sample () {
this.p().then((data) => {
this.stuff = data;
});
//more stuff
}
}
This would allow you to provide a promise-like object, for your unit test, that executes synchronously.
One way would be to periodically check for the set value.
it('test2', function(done) {
let sample = new Sample();
let assert = function() {
if(sample.stuff === 2) {
done();
} else {
setTimeout(assert, 0);
}
};
sample.sample();
assert();
});
It's not the prettiest, and won't give the best error message on a failure, but it would work. If sample.stuff
isn't set to 2
within a couple seconds (I think 3 seconds is the default) then the test will fail because done()
was not called in time.
Another possible option is to have the test replace stuff
with a setter. Then you can expect()
on set.
it('test2', function(done) {
let sample = new Sample();
Object.defineProperty(sample, 'stuff', { set: function (value) {
expect(value).to.be.eql(2);
done();
}});
sample.sample();
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.