从外部访问回调函数的这个对象
Accessing this object of a callback function from outside
我问的可能有点混乱,但我会尽量说清楚。
基本上,我正在使用 mocha/chai 对 Node.JS 服务器的数据访问层进行单元测试。我正在使用 bluebird return 一个 promise 和一个 SQLite 数据库。
这是我要测试的函数插入:
insert(sqlRequest, sqlParams, sqlRequest2) {
return new Promise(function (resolve, reject) {
let insertStatement = this.getDatabase().prepare(sqlRequest);
let getStatement = this.getDatabase().prepare(sqlRequest2);
insertStatement.run(sqlParams, err => {
console.log('this.changes = ', this.changes);
if (this.changes === 1) {
getStatement.all({ $id: this.lastID }, (err, rows) => {
if (err) {
console.log('entered second err');
reject(err);
} else {
resolve(rows[0]);
}
});
} else {
console.log('entered first err ');
reject(err);
}
});
}.bind(this));
}
这就是我对 mocha 的测试:
it('insert : Error 2st SQL query', function (done) {
const daoCommon = new DaoCommon();
daoCommon.getDatabase = () => {
return {
prepare: (sqlRequest) => {
return {
all: (sql, callback) => {
let err = {};
let rows = null;
callback(err, rows);
},
run: (sqlParams, callback) => {
let err = undefined;
callback(err);
}
}
}
}
}
daoCommon.insert('', '', '')
.then(success => {
expect.fail();
})
.catch(error => {
expect(error).to.eql({});
})
.finally(function () {
done();
})
});
我想模拟一个 this.changes
等于 1 的测试,但我不知道 how/where 我可以设置这个值。根据我读到的 this object
来自回调函数,但我不知道它到底来自哪里或如何为我的测试设置它。
更新:
您可以使用方法的 .call
设置正在调用的函数的 this
。
在您的情况下,使用 this.changes
值调用 callback
将类似于:
var thisObject = {
changes: 1
};
callback.call(thisObject, err);
这将设置回调函数的值 this.changes
。
this
的值在 API documentation
中解释
If execution was successful, the this
object will contain two
properties named lastID
and changes
which contain the value of the
last inserted row ID and the number of rows affected by this query
respectively.
意思是callback
函数总会有this.changes
。除非您手动设置 this.changes = something
,否则您无法更改它,我不明白您为什么要这样做。
感谢@Maxali 的评论,我会post回答如下:
You can set this when calling the function callback(err) by using .call(). eg: callback.call({changes:1}, err). this will set changes to 1
请注意,我必须更改此行 insertStatement.run(sqlParams, err => {
,其中我将箭头函数的回调更改为函数声明 insertStatement.run(sqlParams, function(err) {
才能正常工作。我假设这是由于箭头函数中的 this 没有引用函数本身内部的对象。
我问的可能有点混乱,但我会尽量说清楚。
基本上,我正在使用 mocha/chai 对 Node.JS 服务器的数据访问层进行单元测试。我正在使用 bluebird return 一个 promise 和一个 SQLite 数据库。
这是我要测试的函数插入:
insert(sqlRequest, sqlParams, sqlRequest2) {
return new Promise(function (resolve, reject) {
let insertStatement = this.getDatabase().prepare(sqlRequest);
let getStatement = this.getDatabase().prepare(sqlRequest2);
insertStatement.run(sqlParams, err => {
console.log('this.changes = ', this.changes);
if (this.changes === 1) {
getStatement.all({ $id: this.lastID }, (err, rows) => {
if (err) {
console.log('entered second err');
reject(err);
} else {
resolve(rows[0]);
}
});
} else {
console.log('entered first err ');
reject(err);
}
});
}.bind(this));
}
这就是我对 mocha 的测试:
it('insert : Error 2st SQL query', function (done) {
const daoCommon = new DaoCommon();
daoCommon.getDatabase = () => {
return {
prepare: (sqlRequest) => {
return {
all: (sql, callback) => {
let err = {};
let rows = null;
callback(err, rows);
},
run: (sqlParams, callback) => {
let err = undefined;
callback(err);
}
}
}
}
}
daoCommon.insert('', '', '')
.then(success => {
expect.fail();
})
.catch(error => {
expect(error).to.eql({});
})
.finally(function () {
done();
})
});
我想模拟一个 this.changes
等于 1 的测试,但我不知道 how/where 我可以设置这个值。根据我读到的 this object
来自回调函数,但我不知道它到底来自哪里或如何为我的测试设置它。
更新:
您可以使用方法的 .call
设置正在调用的函数的 this
。
在您的情况下,使用 this.changes
值调用 callback
将类似于:
var thisObject = {
changes: 1
};
callback.call(thisObject, err);
这将设置回调函数的值 this.changes
。
this
的值在 API documentation
If execution was successful, the
this
object will contain two properties namedlastID
andchanges
which contain the value of the last inserted row ID and the number of rows affected by this query respectively.
意思是callback
函数总会有this.changes
。除非您手动设置 this.changes = something
,否则您无法更改它,我不明白您为什么要这样做。
感谢@Maxali 的评论,我会post回答如下:
You can set this when calling the function callback(err) by using .call(). eg: callback.call({changes:1}, err). this will set changes to 1
请注意,我必须更改此行 insertStatement.run(sqlParams, err => {
,其中我将箭头函数的回调更改为函数声明 insertStatement.run(sqlParams, function(err) {
才能正常工作。我假设这是由于箭头函数中的 this 没有引用函数本身内部的对象。