在 Jest (React-Redux) 中测试 SVG 元素
Testing for SVG element in Jest (React-Redux)
我有一个为 Reddit 应用程序定义的 User
组件,如下所示:
// User.js
import React from "react";
import { useSelector } from "react-redux";
import { selectUsername, selectAuthState } from "./userSlice";
import Reddit from "../../api/Reddit";
const User = () => {
const userID = useSelector(selectUsername);
const authState = useSelector(selectAuthState);
const { isLoading } = useSelector(state => state.user)
const handleAuth = (e) => {
e.preventDefault();
Reddit.getAccessToken();
}
if (isLoading) {
return (
<svg className="spinner" viewBox="0 0 50 50">
<circle class="path" cx="25" cy="25" r="20" fill="none" stroke-width="5"></circle>
</svg>
)
} else if (authState) {
return (
<a id="reddit-username" target="_blank" rel="noreferrer" href={`https://www.reddit.com/user/${userID}`} aria-label="Current user ID">{userID}</a>
)
} else {
return (
<a id="reddit-username" href="/" onClick={handleAuth} aria-label="Connect the web app with your Reddit account">Link with Reddit</a>
)
}
}
export default User;
到目前为止,组件的测试文件布局如下:
// User.spec.js
import React from 'react';
import { render } from '@testing-library/react';
import { Provider } from 'react-redux';
import { store } from '../../app/store';
import User from "../../features/User/User";
test("renders 'Link with Reddit' link by default", () => {
const { getByText } = render(
<Provider store={store}>
<User />
</Provider>
);
expect(getByText("Link with Reddit")).toBeInTheDocument();
});
我正在尝试编写用于在组件 isLoading
时呈现 SVG 元素的测试,但我不知道如何进行,因为我对 React-Redux 中的测试还很陌生。我应该如何完成它?
您可以为每个具有不同状态的测试用例提供 redux 存储。这样选择器将 return 状态切片具有不同的值。这允许您测试使用这些变量的不同代码分支。
例如
User.jsx
:
import React from 'react';
import { useSelector } from 'react-redux';
const selectUsername = (state) => state.user.name;
const selectAuthState = (state) => state.auth;
export const User = () => {
const userID = useSelector(selectUsername);
const authState = useSelector(selectAuthState);
const { isLoading } = useSelector((state) => state.user);
const handleAuth = (e) => {
e.preventDefault();
};
if (isLoading) {
return (
<svg className="spinner" viewBox="0 0 50 50">
<circle className="path" cx="25" cy="25" r="20" fill="none" strokeWidth="5"></circle>
</svg>
);
} else if (authState) {
return (
<a
id="reddit-username"
target="_blank"
rel="noreferrer"
href={`https://www.reddit.com/user/${userID}`}
aria-label="Current user ID"
>
{userID}
</a>
);
} else {
return (
<a id="reddit-username" href="/" onClick={handleAuth} aria-label="Connect the web app with your Reddit account">
Link with Reddit
</a>
);
}
};
User.test.jsx
:
import { User } from './User';
import React from 'react';
import { render } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import { Provider } from 'react-redux';
import { combineReducers, createStore } from 'redux';
function renderUI(reducers) {
const rootReducer = combineReducers(reducers);
const store = createStore(rootReducer);
return render(
<Provider store={store}>
<User />
</Provider>
);
}
describe('70249367', () => {
test('should render spinner', () => {
const { container } = renderUI({
user: (state = { name: '', isLoading: true }) => {
return state;
},
});
expect(container.querySelector('.spinner')).toBeInTheDocument();
});
test("renders 'Link with Reddit' link by default", () => {
const { getByText } = renderUI({
user: (state = { name: '', isLoading: false }) => {
return state;
},
});
expect(getByText('Link with Reddit')).toBeInTheDocument();
});
test('should render username', () => {
const { getByText } = renderUI({
user: (state = { name: 'teresa teng', isLoading: false }) => {
return state;
},
auth: (state = {}) => state,
});
expect(getByText('teresa teng')).toBeInTheDocument();
});
});
测试结果:
PASS examples/70249367/User.test.jsx (8.809 s)
70249367
✓ should render spinner (27 ms)
✓ renders 'Link with Reddit' link by default (7 ms)
✓ should render username (3 ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 94.74 | 100 | 80 | 93.33 |
User.jsx | 94.74 | 100 | 80 | 93.33 | 13
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 3 passed, 3 total
Snapshots: 0 total
Time: 9.405 s
包版本:
"@testing-library/jest-dom": "^5.11.6",
"@testing-library/react": "^11.2.2",
"jest": "^26.6.3",
"react": "^16.14.0",
"react-dom": "^16.14.0",
"react-redux": "^7.2.2",
"redux": "^4.1.0",
我有一个为 Reddit 应用程序定义的 User
组件,如下所示:
// User.js
import React from "react";
import { useSelector } from "react-redux";
import { selectUsername, selectAuthState } from "./userSlice";
import Reddit from "../../api/Reddit";
const User = () => {
const userID = useSelector(selectUsername);
const authState = useSelector(selectAuthState);
const { isLoading } = useSelector(state => state.user)
const handleAuth = (e) => {
e.preventDefault();
Reddit.getAccessToken();
}
if (isLoading) {
return (
<svg className="spinner" viewBox="0 0 50 50">
<circle class="path" cx="25" cy="25" r="20" fill="none" stroke-width="5"></circle>
</svg>
)
} else if (authState) {
return (
<a id="reddit-username" target="_blank" rel="noreferrer" href={`https://www.reddit.com/user/${userID}`} aria-label="Current user ID">{userID}</a>
)
} else {
return (
<a id="reddit-username" href="/" onClick={handleAuth} aria-label="Connect the web app with your Reddit account">Link with Reddit</a>
)
}
}
export default User;
到目前为止,组件的测试文件布局如下:
// User.spec.js
import React from 'react';
import { render } from '@testing-library/react';
import { Provider } from 'react-redux';
import { store } from '../../app/store';
import User from "../../features/User/User";
test("renders 'Link with Reddit' link by default", () => {
const { getByText } = render(
<Provider store={store}>
<User />
</Provider>
);
expect(getByText("Link with Reddit")).toBeInTheDocument();
});
我正在尝试编写用于在组件 isLoading
时呈现 SVG 元素的测试,但我不知道如何进行,因为我对 React-Redux 中的测试还很陌生。我应该如何完成它?
您可以为每个具有不同状态的测试用例提供 redux 存储。这样选择器将 return 状态切片具有不同的值。这允许您测试使用这些变量的不同代码分支。
例如
User.jsx
:
import React from 'react';
import { useSelector } from 'react-redux';
const selectUsername = (state) => state.user.name;
const selectAuthState = (state) => state.auth;
export const User = () => {
const userID = useSelector(selectUsername);
const authState = useSelector(selectAuthState);
const { isLoading } = useSelector((state) => state.user);
const handleAuth = (e) => {
e.preventDefault();
};
if (isLoading) {
return (
<svg className="spinner" viewBox="0 0 50 50">
<circle className="path" cx="25" cy="25" r="20" fill="none" strokeWidth="5"></circle>
</svg>
);
} else if (authState) {
return (
<a
id="reddit-username"
target="_blank"
rel="noreferrer"
href={`https://www.reddit.com/user/${userID}`}
aria-label="Current user ID"
>
{userID}
</a>
);
} else {
return (
<a id="reddit-username" href="/" onClick={handleAuth} aria-label="Connect the web app with your Reddit account">
Link with Reddit
</a>
);
}
};
User.test.jsx
:
import { User } from './User';
import React from 'react';
import { render } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import { Provider } from 'react-redux';
import { combineReducers, createStore } from 'redux';
function renderUI(reducers) {
const rootReducer = combineReducers(reducers);
const store = createStore(rootReducer);
return render(
<Provider store={store}>
<User />
</Provider>
);
}
describe('70249367', () => {
test('should render spinner', () => {
const { container } = renderUI({
user: (state = { name: '', isLoading: true }) => {
return state;
},
});
expect(container.querySelector('.spinner')).toBeInTheDocument();
});
test("renders 'Link with Reddit' link by default", () => {
const { getByText } = renderUI({
user: (state = { name: '', isLoading: false }) => {
return state;
},
});
expect(getByText('Link with Reddit')).toBeInTheDocument();
});
test('should render username', () => {
const { getByText } = renderUI({
user: (state = { name: 'teresa teng', isLoading: false }) => {
return state;
},
auth: (state = {}) => state,
});
expect(getByText('teresa teng')).toBeInTheDocument();
});
});
测试结果:
PASS examples/70249367/User.test.jsx (8.809 s)
70249367
✓ should render spinner (27 ms)
✓ renders 'Link with Reddit' link by default (7 ms)
✓ should render username (3 ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 94.74 | 100 | 80 | 93.33 |
User.jsx | 94.74 | 100 | 80 | 93.33 | 13
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 3 passed, 3 total
Snapshots: 0 total
Time: 9.405 s
包版本:
"@testing-library/jest-dom": "^5.11.6",
"@testing-library/react": "^11.2.2",
"jest": "^26.6.3",
"react": "^16.14.0",
"react-dom": "^16.14.0",
"react-redux": "^7.2.2",
"redux": "^4.1.0",