Доступ к этому объекту функции обратного вызова извне

Может быть, это немного запутывает то, что я прошу, но я постараюсь быть максимально ясным.

В основном я делаю модульное тестирование с mocha/chai для моего уровня доступа к данным моего сервера Node.JS. Я использую Bluebird, чтобы вернуть обещание и базы данных 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));
    }

И это мой тест с мокко:

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, но я не знаю, как / где я могу установить это значение. Согласно тому, что я прочитал это this object это из функции обратного вызова, но я не знаю точно, откуда она берется или как установить ее для моих тестов.

2 ответа

Решение

Обновление: вы можете установить this функции, с которой вы звоните .call метода. В вашем случае звонит callback с this.changes значение будет выглядеть так:

var thisObject = {
   changes: 1
};
callback.call(thisObject, err);

Это установит значение this.changes вашей функции обратного вызова.


Значение this объясняется в документации API

Если исполнение было успешным, this объект будет содержать два свойства с именем lastID а также changes которые содержат значение последнего вставленного идентификатора строки и количество строк, затронутых этим запросом соответственно.

Это означает, что callback функция всегда будет иметь this.changes, Вы не можете изменить его, если не установите this.changes = something вручную, чего я не понимаю, зачем ты это делаешь.

Спасибо за комментарий @Maxali, я выложу ответ ниже:

Вы можете установить это при вызове функции обратного вызова (err) с помощью.call(). Например: callback.call({изменения:1}, ошибка). это установит изменения в 1

И обратите внимание, что мне пришлось изменить эту строку insertStatement.run(sqlParams, err => { где у меня есть обратный вызов от функции стрелки к объявлению функции insertStatement.run(sqlParams, function(err) { чтобы это работало. Я предполагаю, что это связано с тем, что в функции стрелки не ссылается на объект внутри самой функции.

Другие вопросы по тегам