繁体   English   中英

如何使用 Jest (Amplify API) 模拟 API 调用

[英]How to mock an API call with Jest (Amplify API)

我目前正在使用 AWS Amplify API 开发一个项目。我正在尝试测试一个组件,我正在其中执行 API 后调用(在 checkCredentials 方法中),但想模拟它以测试我的组件的行为,而不是API 电话。

这是我的组件:

const LoginPage = () => {
    const [{username, password}, updateCredentials] = React.useState({username: '', password: ''})
    const [errorMsg, setMsg] = useState('');
    const navigate = useNavigate();
    let invalidLoginMessage = errorMsg

    const checkCredentials = async (event: React.FormEvent) => {
        event.preventDefault();
        try {
            const loginData = await API.post('api', '/login/', {body: {username: username, password: password} })
            if (loginData.message === 'Login Successful'){
                console.log(loginData)
                authStatus.handleLogin(username);
                navigate("/home");
            }
        } catch (err) {console.log('Login Error', {err})} {setMsg("Informations invalides! Merci d'utiliser une adresse @ingeno.ca.")}    
    }

    return(
        <div className="withPadding">
            <form onSubmit={checkCredentials}>
                <div>Merci de vous authentifier afin d'utiliser l'application!</div>
                <label htmlFor="username">Nom d'utilisateur</label>
                <input placeholder='E-mail' data-testid="usernameInput" id="user" value={username} onChange={(event) => updateCredentials({
                    username: event.target.value,
                    password
                })} />
                <label htmlFor="password">Mot de passe</label>
                <input placeholder='Password' data-testid="passwordInput" id="password" type="password" value = {password} onChange={(event) => updateCredentials({
                    username,
                    password: event.target.value,
                })} />
                <Button data-testid="boutonLogin" type = "submit" className="btn-sm">Se connecter</Button>
                <br />
                <h4 style={{ color: 'red' }}>{invalidLoginMessage}</h4>
            </form>
        </div>
    )
} 

这是我目前的测试:

it('should show "invalid credentials" message when invalid credentials', () => {
      render(
        <Router>
          <LoginPage />
        </Router>)

      API.post = jest.fn().mockImplementation( () => { 
          return JSON.parse('{ "message": "Login Error"}')
      });

      const message = screen.getByText(errorMessage)
      const usernameInput = screen.getByPlaceholderText("E-mail")
      const passwordInput = screen.getByPlaceholderText("Password")
      fireEvent.change(usernameInput, {target: {value: invalidTestUser}})
      fireEvent.change(passwordInput, {target: {value: password}})
      userEvent.click(screen.getByTestId("boutonLogin"))

      expect((usernameInput as HTMLInputElement).value).toBe("testusername")
      expect((passwordInput as HTMLInputElement).value).toBe("12345")
      expect(message).toBeInTheDocument();
   })

我收到以下错误:

 TestingLibraryElementError: Unable to find an element with the text: Informations invalides! Merci d'utiliser une adresse @ingeno.ca.. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

现在我想知道我的 API 模拟是否足够,如果不够,如何使用 AWS Amplify API 设法做这样的事情? 我发现很难知道测试失败是因为模拟不好还是页面没有及时更新以显示文本。

编辑

我尝试了一些东西,并且非常确定我的 API 调用模拟是我的测试未通过的原因。 通过在不调用 API 的情况下创建类似的方法,测试顺利通过,因此文本出现了。 我仍然不确定如何模拟 API 调用。

谢谢您的帮助。

可能是LoginPage还在使用真正的API

我通常做类似的事情

// Mock the library before importing it, 
// and before importing Component Under Test

jest.mock('API');

import API from 'api';
import {mocked} from "ts-jest/utils";

const mockAPI = mocked(API);

mockAPI.post.mockImplementation( () => { 
    return JSON.parse('{ "message": "Login Error"}')
});

我想出了我的应用程序。

jest.mock('aws-amplify');

const A_SUCCESS_RESPONSE = { response: 'ok' };
const AN_ERROR_RESPONSE = { response: 'something went wrong' };
const GOOD_USER_NAME = 'good-user-name';
const GOOD_PASSWORD = 'good-password';

it('success example', async () => {
    mocked(API.post).mockResolvedValue(A_SUCCESS_RESPONSE);

    const response = await API.post('api', '/login/', { body: { username: GOOD_USER_NAME, password: GOOD_PASSWORD } });

    expect(response).toEqual(A_SUCCESS_RESPONSE);
});

it('error example', async () => {
    mocked(API.post).mockRejectedValue(AN_ERROR_RESPONSE);
    try {
        await API.post('api', '/login/', { body: { username: GOOD_USER_NAME, password: GOOD_PASSWORD } });
    } catch (error) {
        expect(error).toEqual(AN_ERROR_RESPONSE);
    }
});

您需要首先模拟 aws-amplify 模块,然后使用 mocked 您可以模拟特定请求的已解决或拒绝的值来测试您的组件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM