反応とReduxによるテスト駆動開発:サンク、スライスと要求モッキング
35455 ワード
これらの記事の詳細を読む場合は、躊躇しない私の購読するnewsletter .😁
Reduxで書くテストは間違いなく直感的に聞こえるかもしれません.あなたがReduxで働いているならば、それはさらに複雑に思えるかもしれません.🥶
しかし、機能を追加する前にテストを書く前に、デザインパターン、アーキテクチャ、および使用する変数の名前について前向きに考えるので、より良いコードを書くことができます.🚀
我々は、ユーザー管理ダッシュボードを構築している.基本的には、reduxを使用して考えると、我々はcrudアクションを実行したい.
次に、ユーザは以下のようになります. ユーザを作成します. ユーザを更新します. ユーザを削除します. ユーザーまたはユーザーのリストを取得します. この小さなプロジェクトのユーザは4つの属性を持つでしょう. ID 名前 ユーザ名 メール シンプルさのために、UIコードを書きません.我々は主にテスト環境を作成し、テストを書いて、スライスとthunkを我々が望むものを持っていることを確認することに集中します.
まず第一に、シンプルな反応プロジェクトを作成します.
次に、reduxパッケージをインストールしたいと思います.模擬アダプターは、サーバー上のリクエストをシミュレートするのに役立ちます.
srcディレクトリで新しいディレクトリを作成します
このファイルは以下のメソッドと変数を含みます: mocknetworkresponse :デフォルトのインスタンスでmockアダプタを作成し、必要なエンドポイントに対して任意のGETまたはPOSTリクエストをモックする GetCreateUserResponse : POSTリクエストの応答を返す getUserListResponse : GETリクエストの応答を返す これらの方法を書きましょう.
これは最も興味深い部分です.レッツゴーTDD .🔥
まず、ストアを作成して設定しましょう.srcディレクトリで新しいディレクトリを作成します
“スライス”は、あなたのアプリケーションの単一の機能のためのReduxリダラー論理とアクションのコレクションです.The
スライスのデフォルト状態は空の配列でなければなりません
テストを書いて失敗しましょう.新しいディレクトリを作成する
このディレクトリの中に
最初のテストは、ストアが空であるか未定義であることを確認することです.初期状態はおそらくこのようになります.
に
全く普通.我々は定義していない
スライスディレクトリ内で、ユーザーと呼ばれるファイルを作成します.js
このために、我々はthunkを書く必要があります.thunkは、ストアのディスパッチメソッドを引数として受け取り、後にAPIまたは副作用が終了した後に同期アクションを送信するために使用する関数です.
まず、この機能のテストを書きましょう.
前の状態を保存し、 アクションを派遣し、それが満たされることを確認し、期待される状態と実際の状態を比較する. 繰り返しますが、テストは失敗します.作成したユーザー機能のために、サンクと還元器を加えましょう.
まず、この機能のテストを書きましょう.
減速機とタンクを加えましょう.
すごい!我々はちょうどredux、thunk、およびaxios mockを使用していくつかのテストを書いた.🤩
あなたのための挑戦の少し?ユーザーの削除、変更、およびユーザーの取得の可能性などの機能を追加します.
これらのすべての機能を使用してコードを見つけるhere .
本稿では,rduxによるtddへの簡単な導入を行った.TDDを使用して反応コンポーネントを書くことを探しているならば、あなたは私が書いたこれをチェックすることができます.
そして、あなたの提案や質問は、コメントのセクションで歓迎されるようにすべての記事をより良くすることができます.
記事投稿bloggu.io . 無料でお試しください.
Reduxで書くテストは間違いなく直感的に聞こえるかもしれません.あなたがReduxで働いているならば、それはさらに複雑に思えるかもしれません.🥶
しかし、機能を追加する前にテストを書く前に、デザインパターン、アーキテクチャ、および使用する変数の名前について前向きに考えるので、より良いコードを書くことができます.🚀
プロジェクト
我々は、ユーザー管理ダッシュボードを構築している.基本的には、reduxを使用して考えると、我々はcrudアクションを実行したい.
次に、ユーザは以下のようになります.
プロジェクトのセットアップ
まず第一に、シンプルな反応プロジェクトを作成します.
yarn create react-app react-redux-test-driven-development
プロジェクトが作成されると、プロジェクトの実行によってすべてが動作することを確認します.cd react-redux-test-driven-development
yarn start
そして、あなたは何か似ているhttp://localhost:3000 . 次に、reduxパッケージをインストールしたいと思います.模擬アダプターは、サーバー上のリクエストをシミュレートするのに役立ちます.
# Yarn
yarn add @reduxjs/toolkit axios-mock-adapter axios
すごい!インストールされたら、まずテストのために模擬データを書きましょう.🍔テストのためのデータのモッキング
srcディレクトリで新しいディレクトリを作成します
utils
. 次に、tests.data.js
.このファイルは以下のメソッドと変数を含みます:
/user/
/user/
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
const getCreateUserResponse = {
id: 3,
name: "Clementine Bauch",
username: "Samantha",
email: "[email protected]"
};
const getUserListResponse = [
{
id: 1,
name: "Leanne Graham",
username: "Bret",
email: "[email protected]"
},
{
id: 2,
name: "Ervin Howell",
username: "Antonette",
email: "[email protected]"
},
];
// Adding mock network response that is used in tests
const mockNetWorkResponse = () => {
const mock = new MockAdapter(axios);
mock.onGet(`/users/`).reply(200, getUserListResponse);
mock.onPost(`/users/`).reply(200, getCreateUserResponse);
};
export {
mockNetWorkResponse,
getCreateUserResponse,
getUserListResponse,
};
すごい!モックアダプターで準備ができて、我々は店の初期化とスライスのテストを書くことに集中することができます.書き込みテスト
これは最も興味深い部分です.レッツゴーTDD .🔥
まず、ストアを作成して設定しましょう.srcディレクトリで新しいディレクトリを作成します
index.js
. このファイルで、ストアを初期化します.import { configureStore } from "@reduxjs/toolkit";
import { combineReducers } from "redux";
const rootReducer = combineReducers({
// Adding the reducers
});
export const store = configureStore({
reducer: rootReducer,
});
ユーザスライスの作成
“スライス”は、あなたのアプリケーションの単一の機能のためのReduxリダラー論理とアクションのコレクションです.The
userSlice
は、アクションとリダーズを持っている.スライスのデフォルト状態は空の配列でなければなりません
users
.テストを書いて失敗しましょう.新しいディレクトリを作成する
src/store
呼ばれるslices
.このディレクトリの中に
user.test.js
. このファイルは、私たちが書くテストを含みますuserSlice
. 最初のテストは、ストアが空であるか未定義であることを確認することです.初期状態はおそらくこのようになります.
const initialState = {
users: [],
loading: false,
error: null
};
最初のテストを書きましょう.初期状態のテスト
に
user.test.js
次のテストを追加しますimport reducer, {
initialState,
} from "./user";
/**
* Testing the initial state
*/
test("Should return initial state", () => {
expect(
reducer(undefined, {
type: undefined,
})
).toEqual(initialState);
});
では、yarn test
コマンド.テストは失敗するでしょう.❌全く普通.我々は定義していない
userSlice
, 還元器と初期状態スライスディレクトリ内で、ユーザーと呼ばれるファイルを作成します.js
export const initialState = {
users: [],
loading: false,
error: null
};
export const userSlice = createSlice({
name: "users",
initialState: initialState,
extraReducers: () => {
},
});
export default userSlice.reducer;
また、中にストアのスライス減速剤を登録するstore/index.js
.import { configureStore } from "@reduxjs/toolkit";
import { combineReducers } from "redux";
import { userSlice } from "./slices/user";
const rootReducer = combineReducers({
users: userSlice.reducer,
});
export const store = configureStore({
reducer: rootReducer,
});
テストを再度実行します.✅ユーザの作成テスト
このために、我々はthunkを書く必要があります.thunkは、ストアのディスパッチメソッドを引数として受け取り、後にAPIまたは副作用が終了した後に同期アクションを送信するために使用する関数です.
まず、この機能のテストを書きましょう.
import reducer, {
initialState,
addUser
} from "./user";
import {
mockNetWorkResponse,
getCreateUserResponse,
} from "../../utils/tests.data";
/**
* Testing the createUser thunk
*/
describe("Create a new user", () => {
beforeAll(() => {
mockNetWorkResponse();
});
it("Should be able to create a new user", async () => {
// Saving previous state
const previousState = store.getState().users;
const previousUsers = [...previousState.users];
previousUsers.push(getCreateUserResponse);
// Dispatching the action
const result = await store.dispatch(addUser(getCreateUserResponse));
const user = result.payload;
expect(result.type).toBe("users/addUser/fulfilled");
expect(user).toEqual(getCreateUserResponse);
const state = store.getState().users;
expect(state.users).toEqual(previousUsers);
});
このテストでは、users
更新を行う前に期待される状態にする.これは次の状態を比較するときに役立ちます.import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import axios from "axios";
const addUser = createAsyncThunk("users/addUser", async (user) => {
const res = await axios.post(`/users/`, user);
return res.data;
});
export const initialState = {
users: [],
loading: false,
error: null
};
export const userSlice = createSlice({
name: "users",
initialState: initialState,
extraReducers: () => {
/*
* addUser Cases
*/
builder.addCase(addUser.pending, (state) => {
state.loading = true;
});
builder.addCase(addUser.rejected, (state, action) => {
state.loading = false;
state.error = action.error.message || "Something went wrong";
});
builder.addCase(addUser.fulfilled, (state, action) => {
state.loading = true;
state.users.push(action.payload);
});
},
});
export default userSlice.reducer;
export { addUser };
テストを再度実行してください.✅ユーザのリストを取得するためのテストを書く
まず、この機能のテストを書きましょう.
import reducer, {
initialState,
addUser,
fetchUsers
} from "./user";
import {
mockNetWorkResponse,
getCreateUserResponse,
getUserListResponse
} from "../../utils/tests.data";
...
/**
* Testing the fetchUsers thunk
*/
describe("List all users", () => {
beforeAll(() => {
mockNetWorkResponse();
});
it("Shoudl be able to fetch the user list", async () => {
const result = await store.dispatch(fetchUsers());
const users = result.payload;
expect(result.type).toBe("users/fetchUsers/fulfilled");
expect(users).toEqual(getUserListResponse);
const state = store.getState().users;
expect(state.users).toEqual(getUserListResponse);
});
});
そして、テストが失敗することを確認してください.減速機とタンクを加えましょう.
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import axios from "axios";
const fetchUsers = createAsyncThunk(
"users/fetchUsers",
async () => {
const response = await axios.get(`/users/`);
return response.data;
}
);
const addUser = createAsyncThunk("users/addUser", async (user) => {
const res = await axios.post(`/users/`, user);
return res.data;
});
export const initialState = {
users: [],
loading: false,
error: null
};
export const userSlice = createSlice({
name: "users",
initialState: initialState,
extraReducers: () => {
/*
* addUser Cases
*/
builder.addCase(addUser.pending, (state) => {
state.loading = true;
});
builder.addCase(addUser.rejected, (state, action) => {
state.loading = false;
state.error = action.error.message || "Something went wrong";
});
builder.addCase(addUser.fulfilled, (state, action) => {
state.loading = true;
state.users.push(action.payload);
});
/*
* fetchUsers Cases
*/
builder.addCase(fetchUsers.pending, (state) => {
state.loading = true;
});
builder.addCase(fetchUsers.fulfilled, (state, action) => {
state.loading = false;
state.users = action.payload;
});
builder.addCase(fetchUsers.rejected, (state) => {
state.loading = false;
});
},
});
export default userSlice.reducer;
export { addUser, fetchUsers };
そして、テストは通過しなければなりません.✅すごい!我々はちょうどredux、thunk、およびaxios mockを使用していくつかのテストを書いた.🤩
あなたのための挑戦の少し?ユーザーの削除、変更、およびユーザーの取得の可能性などの機能を追加します.
これらのすべての機能を使用してコードを見つけるhere .
結論
本稿では,rduxによるtddへの簡単な導入を行った.TDDを使用して反応コンポーネントを書くことを探しているならば、あなたは私が書いたこれをチェックすることができます.
そして、あなたの提案や質問は、コメントのセクションで歓迎されるようにすべての記事をより良くすることができます.
記事投稿bloggu.io . 無料でお試しください.
Reference
この問題について(反応とReduxによるテスト駆動開発:サンク、スライスと要求モッキング), 我々は、より多くの情報をここで見つけました https://dev.to/koladev/test-driven-development-with-react-redux-thunk-slices-requests-mocking-585iテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol