与 Sinon/Chai 的第一次通话测试参数

问题描述 投票:0回答:1

我正在尝试为我的单元测试匹配函数调用的参数。

测试代码如下:

  beforeEach(() => {
    enrollmentOffer = offerReadModel(EnrollmentOfferStatuses.Accepted, false, undefined, true)
    fakeSearcher = buildFakeReadModelSearcher()
    ...
  })
  afterEach(() => {
    sinon.restore()
  })

  it('does the right query to get the latest child offer', async () => {
    await expect(calculateRenewInfo(enrollmentOffer as EnrollmentOfferReadModel, true)).to.be.fulfilled
    expect(fakeSearcher.filter).to.have.been.calledWithExactly({
      offerType: { eq: OfferTypes.Child },
      enrollmentOfferId: { eq: enrollmentOffer.id },
    })
  })

目前这个单元测试有以下错误:

  22) calculateRenewInfo
       does the right query to get the latest child offer:
     AssertionError: expected filter to have been called with exact arguments {
  offerType: { eq: 'child' },
  enrollmentOfferId: { eq: '0a1a6e82-c2ca-48ec-9548-c4b5e4d26653' }
}
{ enrollmentOfferId: { eq: '0a1a6e82-c2ca-48ec-9548-c4b5e4d26653' } } {
  offerType: { eq: 'child' },
  enrollmentOfferId: { eq: '0a1a6e82-c2ca-48ec-9548-c4b5e4d26653' }
} 

我认为测试失败的原因是因为有两个调用。第一个内部调用匹配我的测试参数。而第二个,参数是

{ enrollmentOfferId: { eq: '0a1a6e82-c2ca-48ec-9548-c4b5e4d26653' } }
,不匹配它。

通常,我会做这样的事情:

expect(sinonFake.firstCall).to.have.been.calledWith(...)
。然而,这对我不起作用。比如我写
expect(fakeSearcher.filter.firstCall).to.have.been.calledWithExactly(...)
,就会出现错误
Property 'firstCall' does not exist on type '(filters: FilterFor<OfferReadModel>) => Searcher<OfferReadModel>'.

我们用以下方法构建

fakeSearcher

export function buildFakeReadModelSearcher<TReadModel = unknown>(): Partial<Searcher<TReadModel>> {
  const fakeSearcher: Partial<Searcher<TReadModel>> = {}
  fakeSearcher.filter = sinon.fake.returns(fakeSearcher)
  fakeSearcher.afterCursor = sinon.fake.returns(fakeSearcher)
  fakeSearcher.paginatedVersion = sinon.fake.returns(fakeSearcher)
  fakeSearcher.limit = sinon.fake.returns(fakeSearcher)
  fakeSearcher.sortBy = sinon.fake.returns(fakeSearcher)
  fakeSearcher.search = sinon.fake.resolves({ items: [] })
  fakeSearcher.searchOne = sinon.fake.resolves(undefined)
  return fakeSearcher
}

有什么建议/想法我只能匹配第一个电话,而对

fakeSearcher
没有变化或变化很小吗?

javascript unit-testing chai sinon sinon-chai
1个回答
0
投票

问题是

buildFakeReadModelSearcher
说它返回一个
Partial<Searcher<TReadModel>>
所以 Typescript 不知道
fakeSearcher.filter
是 sinon fake.

您可以切换函数以返回包含所有这些假货的对象 + fakeSearcher 对象,然后直接使用这些假货。

export function buildFakeReadModelSearcher<TReadModel = unknown>() {
  const fakeSearcher: Partial<Searcher<TReadModel>> = {}
  const filter = sinon.fake.returns(fakeSearcher)
  const afterCursor = sinon.fake.returns(fakeSearcher)
  const paginatedVersion = sinon.fake.returns(fakeSearcher)
  const limit = sinon.fake.returns(fakeSearcher)
  const sortBy = sinon.fake.returns(fakeSearcher)
  const search = sinon.fake.resolves({ items: [] })
  const searchOne = sinon.fake.resolves(undefined)

  fakeSearcher.filter = filter
  fakeSearcher.afterCursor = afterCursor
  fakeSearcher.paginatedVersion = paginatedVersion
  // ...etc.

  return { fakeSearcher, filter, afterCursor, paginatedVersion, limit, sortBy, search, searchOne }
}

// Then use it like so:
expect(filter.firstCall).to.have.been.calledWithExactly({
  offerType: { eq: OfferTypes.Child },
  enrollmentOfferId: { eq: enrollmentOffer.id },
})
© www.soinside.com 2019 - 2024. All rights reserved.