Как заглушить обязательный модуль в классе? - PullRequest
1 голос
/ 08 ноября 2019

У меня есть класс, который использует базу данных, которую я на самом деле не хочу вызывать. Покопавшись, я нашел Sinon, который, похоже, решил эту проблему для внутренних методов, но не могу заставить его работать с необходимыми модулями. Я знаю, что тест не очень много сейчас, но я хочу подтвердить, что я могу сделать это, прежде чем идти дальше.

Когда я делаю ниже, БД не заглушается.

Код, который я пытаюсь протестировать, выглядит следующим образом:

const db = require('../../models');
const Op = db.Sequelize;

class UserSearch{

  async _resolveUserType(userType){
    let permission;
    if (typeof userType === 'number'){
      permission = await db.permission.findOne({ where: { id : userType } });
    }else{
      permission = await db.permission.findOne({ where: { type : userType } });
    }
    return permission;
  }
}

Код теста:

const db = require('../../models');
const { UserSearch } = require('./userSearch');

describe('UserSearch Test Suite', function(){
it('should return an object', async function(){
        const fakeDb = {
          permission: {
            findOne: function () {
              return new Promise(resolve => {
                return resolve({id: 3, type: 'student'})
              });
            }
          }
        };
        const userSearch = new UserSearch();
        sinon.stub(db, 'permission').returns(fakeDb.permission);
        const permission = await userSearch._resolveUserType(3);
        expect(permission).to.be.an('object');
      });
});

Ответы [ 3 ]

0 голосов
/ 08 ноября 2019

Сначала заглушка, а затем вызывайте тестируемую функцию:

sinon.stub(db, 'permission').returns(fakeDb.permission);
const userSearch = new UserSearch();
const permission = await userSearch._resolveUserType(3);

Если вы сделаете это другим способом, она вызовет исходную функцию без заглушки.

Обычновы устанавливаете заглушки в beforeEach () и очищаете afterEach () в своем наборе тестов.

И да, ваше впечатление правильное в том, что sinon хорошо подходит для устранения внешних зависимостей в вашемблок для тестирования.

0 голосов
/ 08 ноября 2019

Нашел проблему. После проверки объекта db.permission во время запуска я обнаружил, что у него нет метода findOne. Он вызывает метод findOne унаследованного класса Model. Удаляя разрешения, я удалял ссылку наследования.

Я изменил заглушку на

sinon.stub(db.permission, 'findOne').returns(fakeDb.permission.findOne);

и все работало правильно.

0 голосов
/ 08 ноября 2019

Я не уверен, но интересно. Что если переписать кеш?

const { UserSearch } = require('./userSearch');

describe('UserSearch Test Suite', function(){
it('should return an object', async function(){
         require.cache[require.resolve('../../models')].exports = {
          permission: {
            findOne: function () {
              return new Promise(resolve => {
                return resolve({id: 3, type: 'student'})
              });
            }
          }
        };
        const userSearch = new UserSearch();
        const permission = await userSearch._resolveUserType(3);
        expect(permission).to.be.an('object');
      });
});
...