Files
novalon-website/jest.setup.js
T
张翔 7cbb7a9ac8
ci/woodpecker/push/woodpecker Pipeline failed
fix(test): 修复测试环境问题
1. jest.setup.js:
   - 添加 Request/Response/Headers 全局对象 mock
   - 解决 'Request is not defined' 错误

2. .eslintrc.json:
   - 将 jest.setup.js 添加到忽略列表

3. shared-mocks.tsx:
   - 添加 ArrowUp 图标 mock

4. back-to-top.test.tsx:
   - 重写测试使用 import 语法
   - 使用 fireEvent.scroll 触发滚动事件
   - 修复组件渲染测试
2026-03-29 14:50:09 +08:00

181 lines
4.3 KiB
JavaScript

require('@testing-library/jest-dom');
const { TextEncoder, TextDecoder } = require('util');
global.TextEncoder = TextEncoder;
global.TextDecoder = TextDecoder;
if (typeof global.Request === 'undefined') {
global.Request = class Request {
constructor(input, init = {}) {
this.url = typeof input === 'string' ? input : input.url;
this.method = init.method || 'GET';
this.headers = new Map(Object.entries(init.headers || {}));
this.body = init.body;
}
async json() {
return typeof this.body === 'string' ? JSON.parse(this.body) : this.body;
}
};
}
if (typeof global.Response === 'undefined') {
global.Response = class Response {
constructor(body, init = {}) {
this.body = body;
this.status = init.status || 200;
this.statusText = init.statusText || 'OK';
this.headers = new Map(Object.entries(init.headers || {}));
}
async json() {
return typeof this.body === 'string' ? JSON.parse(this.body) : this.body;
}
async text() {
return typeof this.body === 'string' ? this.body : JSON.stringify(this.body);
}
};
}
if (typeof global.Headers === 'undefined') {
global.Headers = class Headers {
constructor(init = {}) {
this._headers = new Map(Object.entries(init));
}
get(name) {
return this._headers.get(name);
}
set(name, value) {
this._headers.set(name, value);
}
};
}
const { setupAllMocks } = require('./src/__mocks__/shared-mocks');
setupAllMocks();
global.console = {
...console,
error: jest.fn(),
warn: jest.fn(),
log: jest.fn(),
};
class MockIntersectionObserver {
constructor(callback, options = {}) {
this.callback = callback;
this.options = options;
this.elements = new Set();
this.observationEntries = [];
}
observe(element) {
this.elements.add(element);
const entry = {
isIntersecting: true,
target: element,
boundingClientRect: element.getBoundingClientRect ? element.getBoundingClientRect() : {},
intersectionRatio: 1,
intersectionRect: {},
rootBounds: {},
time: Date.now(),
};
this.observationEntries.push(entry);
this.callback(this.observationEntries, this);
}
unobserve(element) {
this.elements.delete(element);
}
disconnect() {
this.elements.clear();
this.observationEntries = [];
}
}
global.IntersectionObserver = MockIntersectionObserver;
class MockResizeObserver {
constructor(callback) {
this.callback = callback;
this.elements = new Set();
}
observe(element) {
this.elements.add(element);
this.callback([{ target: element, contentRect: { width: 100, height: 100 } }], this);
}
unobserve(element) {
this.elements.delete(element);
}
disconnect() {
this.elements.clear();
}
}
global.ResizeObserver = MockResizeObserver;
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation(query => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(),
removeListener: jest.fn(),
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});
Object.defineProperty(window, 'scrollTo', {
writable: true,
value: jest.fn(),
});
Object.defineProperty(window, 'localStorage', {
value: {
store: {},
getItem(key) {
return this.store[key] || null;
},
setItem(key, value) {
this.store[key] = value;
},
removeItem(key) {
delete this.store[key];
},
clear() {
this.store = {};
},
},
});
jest.mock('@/db', () => ({
db: {
select: jest.fn().mockReturnValue({
from: jest.fn().mockReturnThis(),
where: jest.fn().mockReturnThis(),
orderBy: jest.fn().mockReturnThis(),
limit: jest.fn().mockReturnThis(),
execute: jest.fn().mockResolvedValue([]),
}),
insert: jest.fn().mockReturnValue({
values: jest.fn().mockReturnThis(),
returning: jest.fn().mockResolvedValue([{ id: 1 }]),
}),
update: jest.fn().mockReturnValue({
set: jest.fn().mockReturnThis(),
where: jest.fn().mockReturnThis(),
returning: jest.fn().mockResolvedValue([{ id: 1 }]),
}),
delete: jest.fn().mockReturnValue({
where: jest.fn().mockReturnThis(),
returning: jest.fn().mockResolvedValue([{ id: 1 }]),
}),
},
}));