在Typescript中,如何仅用一个参数对猫鼬模型的findOne进行存根处理?

时间:2019-12-05 13:23:21

标签: typescript mongoose sinon

我要测试以下功能。它仅用一个参数调用猫鼬模型的findOne():

async function getOne(title: string): Promise<IBook | null> {
  const doc = await Book.findOne({ title })
  return doc as IBook
}

我找不到为不会产生Typescript错误的模型的findOne方法定义存根的方法。下面以两种测试的形式说明了问题。

第一个测试通过,但Typescript报告错误(编译)“ 预期有3-4个参数,但有1.ts(2554)”作为行:

.withArgs({ title: 'A Good Book' }) 

第二个测试没有Typescript错误,但是由于根本没有调用存根,因此它失败了,因为它所包含的参数比被测函数在以下行中使用的参数更多:

.withArgs({ title: 'A Good Book' }, sinon.match.any, sinon.match.any)

我想找到一种解决方案,其中测试通过且Typescript没有报告错误。这是整个测试:

import m from 'mongoose'
import sinon from 'sinon'
import assert from 'assert'

interface IBook {
  title?: string
  category?: string
  price?: number
}

const bookSchema = new m.Schema({
  title: String,
  category: String,
  price: Number
})
const Book = m.model('books', bookSchema)

const book: IBook = {
  title: 'A Good Book',
  category: 'books',
  price: 1
}
const bookDocument = (book as unknown) as m.Document
const sandbox = sinon.createSandbox()

async function getOne(title: string): Promise<IBook | null> {
  const doc = await Book.findOne({ title })
  return doc as IBook
}

describe('getOne test', function() {
  afterEach(function() {
    sandbox.restore()
  })
  specify('typescript error, assert passes', function(done) {
    const findOneStub = sandbox
      .stub(Book, 'findOne')
      .withArgs({ title: 'A Good Book' }) // error: Expected 3-4 arguments, but got 1.ts(2554)
      .resolves(bookDocument)
    getOne('A Good Book').then(function(result) {
      const myBook = result as IBook
      assert(findOneStub.calledOnce)
      assert(myBook.title === 'A Good Book')
      done()
    })
  })
  specify('no typescript error but assert fails', function(done) {
    const findOneStub = sandbox
      .stub(Book, 'findOne')
      .withArgs({ title: 'A Good Book' }, sinon.match.any, sinon.match.any)
      // .withArgs({ title: 'A Good Book' }, undefined, undefined)
      .resolves(bookDocument)
    getOne('A Good Book').then(function(result) {
      const myBook = result as IBook // myBook is undefined
      assert(findOneStub.calledOnce) // fails
      assert(myBook.title === 'A Good Book')
      done()
    })
  })
})

0 个答案:

没有答案