Skip to content

Commit

Permalink
add TestAsyncThunk class for async thunk tests & decomposition loginB…
Browse files Browse the repository at this point in the history
…yUsername.test
  • Loading branch information
stambekovbera committed Dec 1, 2023
1 parent 3908868 commit a9ac6c3
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -1,40 +1,34 @@
import axios from 'axios';
import { loginByUsername } from 'features/AuthByUsername/model/services/loginByUsername/loginByUsername';
import { Dispatch } from '@reduxjs/toolkit';
import { IStateSchema } from 'shared/config/storeConfig/StateSchema';
import { loginByUsername } from './loginByUsername';
import { userActions } from 'entities/User';
import { TestAsyncThunk } from 'shared/lib/tests/TestAsyncThunk/TestAsyncThunk';

jest.mock( 'axios' );

const mockedAxios = jest.mocked( axios, true );

describe( 'loginByUsername.test', () => {
let dispatch: Dispatch;
let getState: () => IStateSchema;

beforeEach( () => {
dispatch = jest.fn();
getState = jest.fn();
} );

test( 'success login', async () => {
const userValue = { username: '123', id: 1 };

mockedAxios.post.mockReturnValue( Promise.resolve( { data: userValue } ) );
const action = loginByUsername( { username: '123', password: '123' } );
const result = await action( dispatch, getState, undefined );
expect( dispatch ).toHaveBeenCalledWith( userActions.setAuthData( userValue ) );
expect( dispatch ).toHaveBeenCalledTimes( 3 );

const thunk = new TestAsyncThunk( loginByUsername );
const result = await thunk.callThunk( { username: '123', password: '123' } );

expect( thunk.dispatch ).toHaveBeenCalledWith( userActions.setAuthData( userValue ) );
expect( thunk.dispatch ).toHaveBeenCalledTimes( 3 );
expect( mockedAxios.post ).toHaveBeenCalled();
expect( result.meta.requestStatus ).toBe( 'fulfilled' );
expect( result.payload ).toEqual( userValue );
} );

test( 'error login', async () => {
mockedAxios.post.mockReturnValue( Promise.resolve( { status: 403 } ) );
const action = loginByUsername( { username: '123', password: '123' } );
const result = await action( dispatch, getState, undefined );
expect( dispatch ).toHaveBeenCalledTimes( 2 );

const thunk = new TestAsyncThunk( loginByUsername );
const result = await thunk.callThunk( { username: '123', password: '123' } );

expect( thunk.dispatch ).toHaveBeenCalledTimes( 2 );
expect( mockedAxios.post ).toHaveBeenCalled();
expect( result.meta.requestStatus ).toBe( 'rejected' );
expect( result.payload ).toBe( 'error' );
Expand Down
25 changes: 25 additions & 0 deletions src/shared/lib/tests/TestAsyncThunk/TestAsyncThunk.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { IStateSchema } from 'shared/config/storeConfig/StateSchema';
import { AsyncThunkAction } from '@reduxjs/toolkit';

type ActionCreatorType<Return, Arg, RejectedValue> = (arg: Arg) => AsyncThunkAction<Return, Arg, {
rejectValue: RejectedValue;
}>

export class TestAsyncThunk<Return, Arg, RejectedValue> {
dispatch: jest.MockedFn<any>;
getState: () => IStateSchema;
actionCreator: ActionCreatorType<Return, Arg, RejectedValue>;

constructor(actionCreator: ActionCreatorType<Return, Arg, RejectedValue>) {
this.actionCreator = actionCreator;
this.dispatch = jest.fn();
this.getState = jest.fn();
}

async callThunk(arg: Arg) {
const action = this.actionCreator( arg );
const result = await action( this.dispatch, this.getState, undefined );

return result;
}
}

0 comments on commit a9ac6c3

Please sign in to comment.