testing
Small context wrapper simplify your mocking and testing.
Installation
#npm i @reatom/testing
Usage
#import { createTestCtx, mockFn } from '@reatom/testing'
export interface TestCtx extends Ctx { mock<T>(anAtom: Atom<T>, fallback: T): Unsubscribe
mockAction<T>(anAction: Action<any[], T>, cb: Fn<[Ctx], T>): Unsubscribe
subscribeTrack<T, F extends Fn<[T]>>( anAtom: Atom<T>, cb?: F, ): F & { unsubscribe: Unsubscribe calls: ReturnType<typeof mockFn<[T], any>>['calls'] lastInput: ReturnType<typeof mockFn<[T], any>>['lastInput'] }}
declare function mockFn<I extends any[], O>( fn?: (...input: I) => O,): ((...input: I) => O) & { calls: Array<{ i: I; o: O }> lastInput: Fn<[], I[0]>}
Story test
#test('createTestCtx', async () => { const add = action<number>() const countAtom = atom((ctx, state = 0) => { ctx.spy(add, ({ payload }) => (state += payload)) return state }) const ctx = createTestCtx() const track = ctx.subscribeTrack(countAtom)
expect(track.calls.length).toEqual(1) expect(track.lastInput()).toEqual(0)
add(ctx, 10) expect(track.calls.length).toEqual(2) expect(track.lastInput()).toEqual(10)
ctx.mockAction(add, (ctx, param) => 100) add(ctx, 10) expect(track.calls.length).toEqual(3) expect(track.lastInput()).toEqual(110)
const unmock = ctx.mock(countAtom, 123) expect(track.calls.length).toEqual(4) expect(track.lastInput()).toEqual(123) add(ctx, 10) expect(track.calls.length).toEqual(4) expect(track.lastInput()).toEqual(123)
unmock() add(ctx, 10) expect(track.calls.length).toEqual(5) expect(track.lastInput()).toEqual(223)})