RFC: Mocking-only aspida client.
LumaKernel opened this issue · comments
Description
create-frourio-app
is now generating a little subtle testing code.
That is set up Fastify one-off instance. This strategy includes some problems. ( For example, port would conflict if there are multiple tests, not so easy to define. )
I suggest providing mocking-only aspida client, like @aspida/mock
.
Main idea is like this. Consider using jest
.
import aspida from '@aspida/axios'
import api from 'path-to-aspida-dir/$api'
const apiClient = api({ baseURL: '' } as any) // only for types
jest.mock('@aspida/axios', () => jest.fn())
;(aspida as any).mockReturnValue({
baseURL: '',
fetch(_prefix: string, prefix1: string, method: string) {
if (prefix1 === apiClient.tasks.$path() && method === 'GET') {
return {
json: () =>
Promise.resolve({
body: [
{ id: 1, label: 'foo task', done: false },
{ id: 2, label: 'bar task', done: true }
]
})
}
}
if (prefix1 === apiClient.token.$path() && method === 'POST') {
return {
json: () =>
Promise.resolve({
body: false
})
}
}
throw new Error('Unmocked path.')
}
})
This is, now not so easy, but works fine.
We may create a type-safe mock library for this idea like following.
import aspida from '@aspida/axios' // NOTE: The client that project using, @aspida/...
import aspidaMock from '@aspida/mock'
import api from 'path-to-aspida-dir/$api'
// NOTE: For achieving not to depend on jest, mock itself self-contained.
aspida.mock(aspidaMock(api)({
tasks: {
$get: [
{ id: 1, label: 'foo task', done: false },
{ id: 2, label: 'bar task', done: true }
]
},
token: {
$post: false
}
}))
// NOTE: We may also want to provide a method to clear.
// aspida.clearMock();
Concise specs
- Unmocked paths/methods are thrown.
Further considerations
- Supporting to accept mocking function.
- e.g.
$get: ({body:{id}}) => `test-user-${id}`
- e.g.
- How does it cost for runtime?
- It costs if using
if (mocked)
. - Use
process.env.NODE_ENV === "test"
internally to avoid runtime cost for bundler users? - Can we use
$get
as string? Or should we provide likeaspidaMock.$get
Symbols to support path like$path
?token: {[aspidaMock.$get]: false}
I've been struggling with the mock ecosystem for almost a year.
This proposal looks good to me.
If I make it dependent on jest, I'll probably release it as @aspida/jest
.
- Create
aspida/aspida-jest
repository - Publish
@aspida/jest
I was assigned to complete this idea. If anyone has questions, suggestions or comments, please leave them here. :)