我遇到的问题是,模拟函数(来自
jest.fn()
)被调用,但该调用未正确注册。我找到了其他人。当他们忘记拨打 await
电话时遇到同样的问题,但我真的不明白这如何适用于我的情况。这是我的测试:
async
该组件只是:
import { render,screen } from '@testing-library/react';
import { default as userEvent } from '@testing-library/user-event';
import { signIn } from 'hooks/__mocks__/auth';
import { LoginButton } from './LoginButton';
jest.mock('hooks/auth');
describe('<LoginButton />', () => {
beforeEach(()=>render(<LoginButton />));
it('should trigger the sign-in process on click', async () => {
const user = userEvent.setup();
await user.click(screen.getByRole('button', { name: 'Sign in' }));
console.log("clicked") // This is the second entry I see logged
expect(signIn).toHaveBeenCalledTimes(1); // Error: received number of calls: 0
});
});
模拟的方法看起来像这样:
export const LoginButton: React.FC = () => {
const signIn = useSignIn();
return (
<Button color="secondary" onClick={signIn}>
Login
</Button>
);
};
我在
export const signIn = jest.fn();
export const useSignIn = () => ()=>{
console.log('signIn'); // This is the first entry I see logged
signIn()
};
之前看到
"signIn"
,所以我不认为这是竞争条件/缺失"clicked
。如果我将 await
替换为 console.log("clicked")
,则测试成功。
不会记录任何警告或错误(除了失败的 signIn()
ofc 之外)。更新
expect
所以我不能使用默认的模拟。我比以前更困惑了。
const signIn = jest.fn();
jest.mock('hooks/auth', ()=>({
useSignIn:() => () =>{
console.log('signIn');
signIn()
}
}));
从模拟
mockFn.mock.results
钩子中获取 signIn
模拟函数。例如
useSignIn()
:
hooks/auth.ts
export const useSignIn = () => {
return () => {
console.log('sign in real implementation');
};
};
:
hooks/__mocks__/auth.ts
export const signIn = jest.fn(() => console.log('mock signIn called'));
export const useSignIn = jest.fn(() => signIn);
:
LoginButton.tsx
import React from 'react';
import { useSignIn } from './hooks/auth';
export const LoginButton: React.FC = () => {
const signIn = useSignIn();
return <button onClick={signIn}>Login</button>;
};
:
LoginButton.test.tsx
测试结果:
import React from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { useSignIn } from './hooks/auth';
import { LoginButton } from './LoginButton';
jest.mock('./hooks/auth');
const useSignInMock = jest.mocked(useSignIn);
describe('<LoginButton />', () => {
beforeEach(() => render(<LoginButton />));
it('should trigger the sign-in process on click', async () => {
const user = userEvent.setup();
await user.click(screen.getByRole('button', { name: 'Login' }));
const signIn = useSignInMock.mock.results[0].value;
expect(signIn).toHaveBeenCalledTimes(1);
});
});