Когда я использую Sinon Mongoose для насмешки над своей моделью пользователя, почему я получаю ошибку TypeError, которая гласит, что User.findById не является функцией? - PullRequest
0 голосов
/ 19 сентября 2019

Кажется, что мой макет Sinon модели User пуст и не распознает вызов findById.Тест также не пройден, поскольку он получает неопределенное значение, но ожидает нулевое значение.Я предполагаю, что это потому, что он не может запустить метод findById и поэтому не может разрешить правильный результат.Когда я запускаю свой комплект jest-тестов, я получаю эту ошибку:

console.error internal/process/next_tick.js:68
TypeError: User.findById is not a function
      at Object.findById [as getUserFieldsById] (C:\Users\apett\web-projects\altcoin-ninjas\crypto-exchange-assistant-full-stack\server\services\User\index.js:6:27)
      at Object.getUserFieldsById (C:\Users\apett\web-projects\altcoin-ninjas\crypto-exchange-assistant-full-stack\server\services\User\__tests__\User.service.test.js:33:10)
      at Object.asyncJestTest (C:\Users\apett\web-projects\altcoin-ninjas\crypto-exchange-assistant-full-stack\server\node_modules\jest-jasmine2\build\jasmineAsyncInstall.js:102:37)
      at resolve (C:\Users\apett\web-projects\altcoin-ninjas\crypto-exchange-assistant-full-stack\server\node_modules\jest-jasmine2\build\queueRunner.js:43:12)
      at new Promise (<anonymous>)
      at mapper (C:\Users\apett\web-projects\altcoin-ninjas\crypto-exchange-assistant-full-stack\server\node_modules\jest-jasmine2\build\queueRunner.js:26:19)
      at promise.then (C:\Users\apett\web-projects\altcoin-ninjas\crypto-exchange-assistant-full-stack\server\node_modules\jest-jasmine2\build\queueRunner.js:73:41)
      at process._tickCallback (internal/process/next_tick.js:68:7)

Файл User.service.test.js:

const sinon = require('sinon');
require('sinon-mongoose');

const User = require('../../../models/User.model');
const UserService = require('../index');

describe('userService test', () => {
  it('has a module', () => {
    expect(UserService).toBeDefined();
  });

  describe('getUserFieldsById method', () => {
    it('should call findById and select with correct args', async () => {
      const MockModel = sinon.mock(User);

      const userId = '5d83c81933cfb51e743b504f';
      const fields = { username: 1 };

      sinon
        .mock(User)
        .expects('findById')
        .withArgs(userId)
        .chain('select')
        .withArgs(fields)
        .resolves(null);

      const userService = UserService(MockModel);
      const result = await userService
        .getUserFieldsById({ userId, fields })
        .catch(console.error);

      MockModel.verify();
      MockModel.restore();
      expect(result).toBeNull();
    });
  });
});

Функция getUserFieldsById:

const getUserFieldsById = User => async ({ userId, fields }) => {
  const user = await User.findById(userId)
    .select(fields)
    .catch(console.error);

  return user;
};

Файл User.model.js:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const mongoosePaginate = require('mongoose-paginate-v2');

const UserSchema = new Schema({
  username: {
    type: String,
    required: true,
  },
  email: {
    type: String,
    required: true,
  },
  normalizedEmail: {
    type: String,
    required: true,
  },
  password: {
    type: String,
    required: true,
  },
  role: {
    type: String,
    required: true,
  },
  avatar: {
    type: String,
  },

  binance: {
    key: {
      type: String,
      default: '',
    },

    secret: {
      type: String,
      default: '',
    },
    credentialsComplete: { type: Boolean, default: false },
    avgRates: [
      {
        symbol: {
          type: String,
          required: true,
        },
        currentAvgRate: {
          type: String,
          required: true,
        },
        currentQty: {
          type: String,
          required: true,
        },
      },
    ],
  },

  tradeProfile: {
    riskPerTrade: { type: String, default: '' },
    pairingPreference: { type: String, default: '' },
    rateOfReturn: { type: String, default: '' },
    profileComplete: { type: Boolean, default: false },
  },
  notifications: {
    email: {
      connected: { type: Boolean, default: true },
      enabled: { type: Boolean, default: true },
      perTrade: {
        enabled: {
          type: Boolean,
          default: false,
        },
      },
      profitReport: {
        enabled: {
          type: Boolean,
          default: false,
        },
        interval: {
          type: String,
          default: 'WEEKLY',
        },
      },
    },
    discord: {
      connected: { type: Boolean, default: false },
      enabled: { type: Boolean, default: false },
      id: { type: String, default: '' },
      perTrade: {
        enabled: {
          type: Boolean,
          default: false,
        },
      },
      profitReport: {
        enabled: {
          type: Boolean,
          default: false,
        },
        interval: {
          type: String,
          default: 'WEEKLY',
        },
      },
    },
    telegram: {
      connected: { type: Boolean, default: false },
      enabled: { type: Boolean, default: false },
      id: { type: String, default: '' },
      perTrade: {
        enabled: {
          type: Boolean,
          default: false,
        },
      },
      profitReport: {
        enabled: {
          type: Boolean,
          default: false,
        },
        interval: {
          type: String,
          default: 'WEEKLY',
        },
      },
    },
  },
  coinBlacklist: [String],
  accountStatus: {
    showGreeting: {
      type: Boolean,
      default: true,
    },
    loggedIn: {
      type: Boolean,
      default: false,
    },
    locked: {
      type: Boolean,
      default: false,
    },
    eligible: {
      type: Boolean,
      default: false,
    },
    verified: {
      type: Boolean,
      default: false,
    },
    active: {
      type: Boolean,
      default: false,
    },
    activated: {
      type: Boolean,
      default: false,
    },
  },
  verificationCode: {
    type: String,
  },
  lastLoggedIn: {
    type: Date,
    default: Date.now(),
  },
  registrationDate: {
    type: Date,
    default: Date.now(),
  },
});

UserSchema.plugin(mongoosePaginate);

module.exports = User = mongoose.model('users', UserSchema);

Кто-нибудь знает, почему это происходит?Я следовал за документами в sinon-mongoose .

...