我正在尝试为我的单元测试匹配函数调用的参数。
测试代码如下:
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
没有变化或变化很小吗?
问题是
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 },
})