Javascript 如何使用Jest模拟导入模块中的函数?
我有一个名为authProvider.js的模块,当我在api.js中测试我的一个函数时,我想模拟它。 我已经在我的jest配置中设置了“automock”:true 这是我的结构Javascript 如何使用Jest模拟导入模块中的函数?,javascript,jestjs,msal,Javascript,Jestjs,Msal,我有一个名为authProvider.js的模块,当我在api.js中测试我的一个函数时,我想模拟它。 我已经在我的jest配置中设置了“automock”:true 这是我的结构 src |-auth | |-__mocks__ | | |-authProvider.js | |-authProvider.js |-utils |-api.js |-api.test.js 这是我迄今为止尝试过的,但仅在第一个测试用例中成功。我不知道如何在第二个测试用例中设置
src
|-auth
| |-__mocks__
| | |-authProvider.js
| |-authProvider.js
|-utils
|-api.js
|-api.test.js
这是我迄今为止尝试过的,但仅在第一个测试用例中成功。我不知道如何在第二个测试用例中设置模拟
api.test.js
import { mockAuthProvider } from "../auth/__mocks__/authProvider";
import { getDefaultHeaders, getValueIndexByColumnName } from './api';
describe('API utils', () => {
describe('getDefaultHeaders', () => {
it('Not authenticated', async () => {
expect(await getDefaultHeaders()).toEqual({
'Content-Type': 'application/json'
});
});
it('Authenticated', async () => {
mockAuthProvider.getAccount.mockImplementationOnce(() =>
Promise.resolve({user: 'test'})
);
const headers = await getDefaultHeaders();
expect(mockAuthProvider.getAccount).toBeCalled();
expect(headers).toEqual({
Authorization: 'Bearer abc123',
'Content-Type': 'application/json'
});
});
});
});
api.js
import { authProvider } from '../auth/authProvider';
import settings from '../settings';
export async function getDefaultHeaders() {
const account = await authProvider.getAccount();
const authenticationParameters = {
scopes: ['api://' + settings.AD_CLIENT_ID + '/login'],
redirectUri: window.location.origin + '/auth.html'
};
let token;
if (account) {
try {
token = await authProvider.acquireTokenSilent(authenticationParameters);
} catch (error) {
token = await authProvider.acquireTokenPopup(authenticationParameters);
}
}
if (token) {
return {
Authorization: `Bearer ${token.accessToken}`,
'Content-Type': 'application/json'
}
}
return {
'Content-Type': 'application/json'
}
}
__mocks\uu\u/authProvider.js
const mockAuthProvider = {
getAccount: jest.fn(),
acquireTokenSilent: jest.fn(),
acquireTokenPopup: jest.fn()
};
module.exports = {
mockAuthProvider
};
错误消息
Expected number of calls: >= 1
Received number of calls: 0
18 | const headers = await getDefaultHeaders();
19 |
> 20 | expect(mockAuthProvider.getAccount).toBeCalled();
| ^
更新
我添加了一个文件来模拟导出auth提供者的整个模块,但我认为这仍然不是解决这个问题的最佳方法。我很难在多个测试用例中使用它,因为我需要按特定顺序指定返回值
有没有更好的办法来解决这个问题
__mocks _u/react-aad-msal.js
import React from 'react';
const errorObj = {
message: 'Some error'
};
export const mockGetAccount = jest.fn()
.mockReturnValueOnce(null) // Not authenticated
.mockReturnValueOnce({user: 'test'}) // Authenticated silent
.mockReturnValueOnce({user: 'test'}); // Authenticated popup
export const mockAcquireTokenSilent = jest.fn()
.mockReturnValueOnce({accessToken: 'abc123'}) // Authenticated silent
.mockRejectedValueOnce(errorObj); // Authenticated popup
export const mockAcquireTokenPopup = jest.fn()
.mockReturnValueOnce({accessToken: 'abc123'}); // Authenticated popup
export const MsalAuthProvider = jest.fn(() => ({
getAccount: mockGetAccount,
acquireTokenSilent: mockAcquireTokenSilent,
acquireTokenPopup: mockAcquireTokenPopup
}));
export const AuthenticationState = {
Authenticated: 'Authenticated',
Unauthenticated: 'Unauthenticated'
};
export const LoginType = {
Popup: 'popup'
};
export const AuthenticationActions = {
Initializing: 'Initializing',
Initialized: 'Initialized',
AcquiredIdTokenSuccess: 'AcquiredIdTokenSuccess',
AcquiredAccessTokenSuccess: 'AcquiredAccessTokenSuccess',
AcquiredAccessTokenError: 'AcquiredAccessTokenError',
LoginSuccess: 'LoginSuccess',
LoginError: 'LoginError',
AcquiredIdTokenError: 'AcquiredIdTokenError',
LogoutSucc: 'LogoutSucc',
AuthenticatedStateChanged: 'AuthenticatedStateChanged'
};
export const AzureAD = ({children}) => <div>{children}</div>;
第二次测试显示了什么错误?我在帖子中添加了错误消息
import { getDefaultHeaders, axiosCreate, getValueIndexByColumnName } from './api';
describe('API utils', () => {
describe('getDefaultHeaders', () => {
it('Not authenticated', async () => {
const headers = await getDefaultHeaders();
expect(headers).toEqual({
'Content-Type': 'application/json'
});
});
it('Authenticated silent', async () => {
const headers = await getDefaultHeaders();
expect(headers).toEqual({
Authorization: 'Bearer abc123',
'Content-Type': 'application/json'
});
});
it('Authenticated popup', async () => {
const headers = await getDefaultHeaders();
expect(headers).toEqual({
Authorization: 'Bearer abc123',
'Content-Type': 'application/json'
});
});
});
describe('axiosCreate', () => {
it('Create axios API base', () => {
expect(axiosCreate()).toBeTruthy();
});
});
describe('getValueIndexByColumnName', () => {
it('Invalid input data', () => {
expect(getValueIndexByColumnName([], null)).toEqual(null);
expect(getValueIndexByColumnName(['column1'], null)).toEqual(-1);
});
it('Valid input data', () => {
expect(getValueIndexByColumnName(['column1'], 'column')).toEqual(-1);
expect(getValueIndexByColumnName(['column1'], 'column1')).toEqual(0);
expect(getValueIndexByColumnName(['column1', 'column2', 'column3'], 'column2')).toEqual(1);
});
});
});