React Jest:如何模拟服务?
问题
我正在寻找一种嘲笑我的KeyCloak服务的方法,称为userService
。实际上,我只需要模拟isloggedin
和登录
函数。我认为这不是一项艰巨的任务,但是经过几个小时的尝试,我仍然无法为此问题找到工作解决方案。
代码示例
uservice.js
import Keycloak from "keycloak-js";
const _kc = new Keycloak({
url: "http://localhost:80",
realm: "realmName",
clientId: "clientName"
});
const initKeycloak = (onAuthenticatedCallback, onNotAuthenticatedCallback) => {
_kc.init(
{
onLoad: 'check-sso',
silentCheckSsoRedirectUri: window.location.origin + '/silent-check-sso.html',
pkceMethod: 'S256',
checkLoginIframe: false
}
)
.then((authenticated) => {
if (!authenticated) {
console.error("user is not authenticated..!");
}
onAuthenticatedCallback();
})
.catch((error) => {
onNotAuthenticatedCallback();
})
};
const doLogin = _kc.login;
const doLogout = _kc.logout;
const getToken = () => {
return _kc.token;
}
const isLoggedIn = () => {
if (_kc.token) {
return true;
} else {
return false;
}
}
const updateToken = (successCallback) => {
_kc.updateToken(5)
.then(successCallback)
.catch(doLogin);
}
const getUsername = () => _kc.tokenParsed?.preferred_username;
const hasRole = (roles) => {
return roles.some((role) => _kc.hasRealmRole(role));
}
const UserService = {
initKeycloak,
doLogin,
doLogout,
isLoggedIn,
getToken,
updateToken,
getUsername,
hasRole,
};
export default UserService;
我已经尝试使用jest.mock()
函数。因此,现在我可以无错误地推开loginbutton,但是AddButton仍然没有激活。
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { BrowserRouter } from "react-router-dom";
import OrganizationsPage from "./OrganizationsPage";
import { act } from "react-test-renderer";
jest.mock("../Services/UserService", () => ({
...jest.requireActual("../Services/UserService"),
doLogin: jest.fn(() => { return true }),
isLoggedIn: jest.fn(() => { return true }),
}));
const MockedOrganizationsPage = () => {
return (
<BrowserRouter>
<OrganizationsPage />
</BrowserRouter>
);
}
describe('OrganizationsPage Alter', () => {
it('should activate alter buttons on login', async () => {
// console.log(UserService.isLoggedIn())
await act(async () => render(<MockedOrganizationsPage />))
const loginButton = screen.getByText("Login");
userEvent.click(loginButton);
const addButton = screen.getByText("Add Organization");
userEvent.click(addButton);
})
})
Problem
I am looking for a way to mock my keycloak service called UserService
. Actually I just need to mock the isLoggedIn
and the login
functions. I do not think this is a difficult task, but after some hours of trying I am still not able to get a working solution for this problem.
Code Samples
UserService.js
import Keycloak from "keycloak-js";
const _kc = new Keycloak({
url: "http://localhost:80",
realm: "realmName",
clientId: "clientName"
});
const initKeycloak = (onAuthenticatedCallback, onNotAuthenticatedCallback) => {
_kc.init(
{
onLoad: 'check-sso',
silentCheckSsoRedirectUri: window.location.origin + '/silent-check-sso.html',
pkceMethod: 'S256',
checkLoginIframe: false
}
)
.then((authenticated) => {
if (!authenticated) {
console.error("user is not authenticated..!");
}
onAuthenticatedCallback();
})
.catch((error) => {
onNotAuthenticatedCallback();
})
};
const doLogin = _kc.login;
const doLogout = _kc.logout;
const getToken = () => {
return _kc.token;
}
const isLoggedIn = () => {
if (_kc.token) {
return true;
} else {
return false;
}
}
const updateToken = (successCallback) => {
_kc.updateToken(5)
.then(successCallback)
.catch(doLogin);
}
const getUsername = () => _kc.tokenParsed?.preferred_username;
const hasRole = (roles) => {
return roles.some((role) => _kc.hasRealmRole(role));
}
const UserService = {
initKeycloak,
doLogin,
doLogout,
isLoggedIn,
getToken,
updateToken,
getUsername,
hasRole,
};
export default UserService;
I already tried to use the jest.mock()
function. So now I can push the loginButton without an error, but the addButton still does not activate.
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { BrowserRouter } from "react-router-dom";
import OrganizationsPage from "./OrganizationsPage";
import { act } from "react-test-renderer";
jest.mock("../Services/UserService", () => ({
...jest.requireActual("../Services/UserService"),
doLogin: jest.fn(() => { return true }),
isLoggedIn: jest.fn(() => { return true }),
}));
const MockedOrganizationsPage = () => {
return (
<BrowserRouter>
<OrganizationsPage />
</BrowserRouter>
);
}
describe('OrganizationsPage Alter', () => {
it('should activate alter buttons on login', async () => {
// console.log(UserService.isLoggedIn())
await act(async () => render(<MockedOrganizationsPage />))
const loginButton = screen.getByText("Login");
userEvent.click(loginButton);
const addButton = screen.getByText("Add Organization");
userEvent.click(addButton);
})
})
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
因此,我找到了解决方案:
我不必模拟
uservice.js
文件,而是keycloak-js
-module。为此,我创建了一个名为__模拟__
的文件夹,然后放入模拟的模块中。开玩笑会自动知道从模拟文件夹而不是节点模块调用keycloak-js。src/模拟/keycloak-js.js:
So I found the solution:
I do not have to mock the
UserService.js
file but more thekeycloak-js
-module. For this I create a folder called__mocks__
and put in my mocked module. Jest will automatically know to call keycloak-js from the mocks folder instead of node-modules.src/mocks/keycloak-js.js: