我创建了一个沙箱来概述主要的兴趣点: https://codesandbox.io/s/restless-dawn-nwy0l
请忽略格式,因为这只是我放在一起的 MWE。
当我在上面的沙箱中运行以下 test 时
import React from "react";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import "@testing-library/jest-dom";
import Statistics from "../src/components/Block/Statistics";
import { IAction, IState } from "../src/typings/AppTypes";
import { AppReducer } from "../src/reducers/AppReducer";
import { AppContext } from "../src/context/AppContext";
import * as MineUtil from "../src/utils/mine";
import * as ConversionUtil from "../src/utils/conversion";
const state: IState = {
verifiedTrans: [
{
to: "A",
from: "B",
amount: 1.23,
message: "First Transaction",
signature: "AB1.23"
},
{
to: "A",
from: "C",
amount: 456.78,
message: "Second Transaction",
signature: "AC456.78"
},
{
to: "A",
from: "D",
amount: 999.99,
message: "Third Transaction",
signature: "AD999.99"
},
{
to: "A",
from: "E",
amount: 987.65,
message: "Forth Transaction",
signature: "AE987.65"
},
{
to: "A",
from: "F",
amount: 1.01,
message: "Fifth Transaction",
signature: "AF1.01"
}
],
selectedTrans: [
{
to: "A",
from: "C",
amount: 456.78,
message: "Second Transaction",
signature: "AC456.78"
}
],
chain: [
{
index: 0,
prevHash: "",
currHash: new Array(64).fill("0").join(""),
transactions: [],
timestamp: Date.parse("04/31/2021"),
merkleRoot: "",
valid: true
},
{
index: 1,
prevHash: new Array(64).fill("0").join(""),
currHash: new Array(64).fill("A").join(""),
transactions: [
{
to: "A",
from: "E",
amount: 987.65,
message: "Forth Transaction",
signature: "AE987.65"
}
],
timestamp: Date.parse("05/01/2021"),
merkleRoot: "987.65EForthTransactionAE987.65A",
valid: true
}
],
preview: {
index: 2,
timestamp: Date.parse("05/02/2021"),
prevHash: new Array(64).fill("A").join(""),
currHash: "",
transactions: [],
merkleRoot: "",
valid: false
}
};
const dispatch = (action: IAction) => AppReducer(state, action);
it("keeps mining button disabled after mining due to valid solution", async () => {
const solution =
"000a4fda363405b2796986a63e8cedde080e1f29ed774f5f93bd97c42b9a96fc0";
const target =
"000b4fda363405b2796986a63e8cedde080e1f29ed774f5f93bd97c42b9a96fc0";
jest.spyOn(MineUtil, "createTarget").mockReturnValue(Promise.resolve(target));
jest
.spyOn(ConversionUtil, "digestMessage")
.mockReturnValue(Promise.resolve(solution));
render(
<AppContext.Provider value={{ state, dispatch }}>
<Statistics chain={false} />
</AppContext.Provider>
);
expect(screen.getByRole("button", { name: /Block Mine/i })).toBeEnabled();
// need to await state changes
fireEvent.click(screen.getByRole("button", { name: /Block Mine/i }));
await waitFor(() => {
expect(screen.getByRole("button", { name: /Block Mine/i })).toBeDisabled();
});
await waitFor(() => {
expect(
screen.getByRole("textbox", { name: /Block Solution/i })
).toHaveClass("valid-solution");
});
});
我明白了:
该测试只是检查如果您在选定交易后按下挖掘按钮,该按钮将变为禁用状态,并且一旦挖掘出有效解决方案,它的类别就会发生变化,从而变为绿色文本(对于此组件)。由于解决方案有效,该按钮也应保持禁用状态。
此外,预览块将变为绿色,但这超出了本单元测试的范围。
但是,似乎状态预览块(它确定解决方案输入文本框上的类)在测试环境中没有正确更新。在开发过程中,情况并非如此,一切都按预期进行。
有什么建议/提示吗?
答案 0 :(得分:2)
在您的测试中,您设置了 value, dispatch
的模拟版本,当您点击 Block mine
按钮时不会触发更新。
但在实际代码中,在 App.tsx
中,您使用 useReducer
钩子(在深处它会触发重新渲染,并且新的 props 通过 Context 传递给 Statistics
)。
要修复它,只需使用 useReducer
const Wrapper = () => {
const [state, dispatch] = useReducer(AppReducer, inititalValues);
return (
<AppContext.Provider value={{ state, dispatch }}>
<Statistics chain={false} />
</AppContext.Provider>
);
};
render(<Wrapper />);
inititalValues
是第 12 行的变量 state
工作沙盒 here