我正在构建一个twitter克隆应用程序,我正在使用TDD。我已经到了尝试测试用户是否能够编辑tweet的地步。其想法是,如果用户单击当前tweet,它将再次显示输入,以便您可以根据需要编辑当前tweet。然后您再次单击tweet按钮,它将设置tweet。
我已经在Storybook中手动测试过了,它的工作原理和我预期的一样,但是,我无法让我的jest测试通过。Jest在测试失败时打印DOM,它仍然显示“我的第一条推文”在DOM中。我猜这是一个时间问题,但是我不知道如何修复它。我试过act
和waitFor
,但是这两个都不起作用。我做错了什么?
渲染我的组件
beforeEach(() => {
renderResult = render(
<Tweet profilePic={imageUrl} username="ndland" title="Tweet Title" />,
);
});
字符串
测试编辑推文
describe("editing a tweet", () => {
const user = userEvent.setup();
let input: Element;
beforeEach(async () => {
input = screen.getByPlaceholderText("What's happening?");
const button = screen.getByRole("button", { name: "Tweet" });
await act(async () => {
await user.click(input);
await user.keyboard("My First Tweet");
await user.click(button);
});
});
it("should allow a user to edit their tweet", async () => {
const twxxt = screen.getByText("My First Tweet");
expect(twxxt).toBeInTheDocument();
expect(screen.queryByText("My edited Tweet")).not.toBeInTheDocument();
await user.click(twxxt);
expect(input).toHaveValue("My First Tweet");
await user.keyboard("My edited Tweet");
await user.click(screen.getByRole("button", { name: "Tweet" }));
await waitFor(() => expect(input).toHaveValue("My edited Tweet"));
});
});
型
问题组件
const Tweet: React.FC<TweetProps> = ({ profilePic, username, title }) => {
const [input, setInput] = React.useState<string | undefined>(undefined);
const [tweet, setTweet] = React.useState<string | undefined>(undefined);
const [placeholder, setPlaceholder] = React.useState<string | undefined>(
"What's happening?",
);
const [placeholderColor, setPlaceholderColor] = React.useState<string>(
"placeholder:text-slate-400",
);
const [likes, setLikes] = React.useState<number>(0);
const [hasLiked, setHasLiked] = React.useState<boolean>(false);
const handleTweet = () => {
if (!input) {
setPlaceholder("Enter a twxxt");
setPlaceholderColor("placeholder:text-red-500");
}
setTweet(input);
};
const handleLike = () => {
if (hasLiked) {
setLikes(likes - 1);
setHasLiked(false);
return;
}
if (input && !hasLiked) {
setLikes(likes + 1);
setHasLiked(true);
}
};
const handleTwxxtClick = () => {
setPlaceholder(tweet);
setTweet(undefined);
};
return (
<div className="dark:bg-slate-800 mx-auto m-4 max-w-md overflow-hidden rounded-xl bg-white shadow-md md:max-w-2xl p-4 flex flex-row space-x-8">
<div className="relative w-16 h-16 flex-shrink-0">
<div>
<Image
className="rounded-full h-full w-full object-cover absolute"
src={profilePic}
alt="Profile Picture"
width={100} // note: see https://nextjs.org/docs/app/building-your-application/optimizing/images#remote-images for more info
height={100}
/>
</div>
</div>
<div className="flex-grow">
<div
aria-label="username"
className="text-indigo-500 font-semibold md:text-lg py-2"
>
@{username}
</div>
<div aria-label="title" className="dark:text-white font-semibold">
{title}
</div>
{tweet ? (
<>
<div
onClick={handleTwxxtClick}
className="dark:text-white py-4 hover:cursor-pointer"
>
{tweet}
</div>
<div className="flex justify-normal space-x-2 items-center">
{likes === 0 ? (
<FontAwesomeIcon
aria-label="like"
onClick={handleLike}
className="text-white"
size="xl"
icon={outlineThumb}
/>
) : (
<FontAwesomeIcon
aria-label="like"
onClick={handleLike}
className="text-white"
size="xl"
icon={solidThumb}
/>
)}
{likes !== 0 && (
<div aria-label="likes" className="text-gray-400">
Likes: {likes}
</div>
)}
</div>
</>
) : (
<>
<input
type="text"
placeholder={placeholder}
value={tweet}
onChange={(e) => setInput(e.target.value)}
className={`w-full my-2 p-2 rounded-md dark:bg-slate-800 dark:text-white dark:border-2 dark:border-indigo-800 ${placeholderColor}`}
/>
<div className="flex justify-end items-center">
<button
onClick={handleTweet}
className="bg-indigo-500 text-white rounded-full px-4 py-2"
>
Tweet
</button>
</div>
</>
)}
</div>
</div>
);
};
export default Tweet;
型
edit忘记添加测试失败。
●推文›编辑推文›应该允许用户编辑他们的推文
expect(element).toHaveValue(My edited Tweet)
Expected the element to have value:
My edited Tweet
Received:
My First Tweet
型
edit 2:我在运行测试时看到以下输出:
<input
aria-label="tweet input"
class="w-full my-2 p-2 rounded-md dark:bg-slate-800 dark:text-white dark:border-2 dark:border-indigo-800 placeholder:text-slate-400"
placeholder="My First Tweet"
type="text"
value=""
/>
型
这告诉我它正在命中处理程序,但是当我调用user.keyboard
时,它并没有将这些键发送给input
。我还添加了@杨柳建议的行,所以input
现在应该有焦点。
2条答案
按热度按时间qncylg1j1#
正如我在评论中提到的,试试这个:
字符串
jvidinwx2#
好吧,看起来问题是,我为我的Assert引用了错误的对象。我引用的
input
对象仍然持有原始值'My First Tweet'。下面是修改后的测试,它按预期通过:字符串
在这个例子中,我只是把
screen.getBy...
拉到一个帮助函数中,所以我可以类似地重用代码,但是现在,当我需要更新对象时,我可以很容易地做到这一点。一个简单问题的简单解决方案,只是我的疏忽。希望这能有所帮助。