refactor: extend vitest setup with full chrome/browser mocks and i18n utility mock
This commit is contained in:
+36
-13
@@ -1,18 +1,29 @@
|
||||
import '@testing-library/jest-dom';
|
||||
import { vi, beforeEach, afterEach } from 'vitest';
|
||||
import { afterEach, beforeEach, vi } from 'vitest';
|
||||
|
||||
vi.mock('@/utils/useLazyTranslation', () => ({
|
||||
useLazyTranslation: (ns?: string) => ({
|
||||
// 自动承接命名空间前缀过滤,100% 模拟真实多语种直出
|
||||
t: (key: string) => (ns ? `${ns}:${key}` : key),
|
||||
i18n: {
|
||||
changeLanguage: vi.fn().mockResolvedValue(undefined),
|
||||
language: 'zh-CN',
|
||||
},
|
||||
isLoaded: true,
|
||||
}),
|
||||
}));
|
||||
|
||||
// Mock react-i18next
|
||||
vi.mock('react-i18next', () => ({
|
||||
useTranslation: () => ({
|
||||
t: (key: string) => key,
|
||||
i18n: {
|
||||
changeLanguage: vi.fn(),
|
||||
changeLanguage: vi.fn().mockResolvedValue(undefined),
|
||||
language: 'zh-CN',
|
||||
},
|
||||
}),
|
||||
initReactI18next: {
|
||||
type: '3rdParty',
|
||||
init: vi.fn(),
|
||||
init: vi.fn().mockResolvedValue(undefined),
|
||||
},
|
||||
}));
|
||||
|
||||
@@ -36,14 +47,14 @@ const storageMock = {
|
||||
},
|
||||
};
|
||||
|
||||
Object.defineProperty(global, 'chrome', {
|
||||
value: {
|
||||
const webExtensionMock = {
|
||||
storage: storageMock,
|
||||
tabs: {
|
||||
query: vi.fn().mockResolvedValue([]),
|
||||
get: vi.fn(),
|
||||
get: vi.fn().mockResolvedValue({}),
|
||||
sendMessage: vi.fn().mockResolvedValue(undefined),
|
||||
create: vi.fn().mockResolvedValue({}),
|
||||
reload: vi.fn().mockResolvedValue(undefined), // ✅ 承接 MessageAction.RELOAD_TAB 刷新单元测试
|
||||
},
|
||||
runtime: {
|
||||
id: 'test-extension-id',
|
||||
@@ -59,6 +70,7 @@ Object.defineProperty(global, 'chrome', {
|
||||
addListener: vi.fn(),
|
||||
removeListener: vi.fn(),
|
||||
},
|
||||
openPopup: vi.fn().mockResolvedValue(undefined),
|
||||
},
|
||||
sidePanel: {
|
||||
open: vi.fn().mockResolvedValue(undefined),
|
||||
@@ -70,6 +82,13 @@ Object.defineProperty(global, 'chrome', {
|
||||
getAll: vi.fn().mockResolvedValue([]),
|
||||
remove: vi.fn().mockResolvedValue(undefined),
|
||||
},
|
||||
alarms: {
|
||||
create: vi.fn().mockResolvedValue(undefined),
|
||||
onAlarm: {
|
||||
addListener: vi.fn(),
|
||||
removeListener: vi.fn(),
|
||||
},
|
||||
},
|
||||
contextMenus: {
|
||||
create: vi.fn(),
|
||||
onClicked: {
|
||||
@@ -92,13 +111,18 @@ Object.defineProperty(global, 'chrome', {
|
||||
ACTION: 'action',
|
||||
},
|
||||
},
|
||||
},
|
||||
writable: true,
|
||||
});
|
||||
};
|
||||
|
||||
Object.defineProperty(globalThis, 'chrome', { value: webExtensionMock, writable: true });
|
||||
Object.defineProperty(globalThis, 'browser', { value: webExtensionMock, writable: true });
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
Object.defineProperty(window, 'chrome', { value: webExtensionMock, writable: true });
|
||||
Object.defineProperty(window, 'browser', { value: webExtensionMock, writable: true });
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
// Ensure storage mocks return objects even after clearAllMocks
|
||||
storageMock.local.get.mockResolvedValue({});
|
||||
storageMock.session.get.mockResolvedValue({});
|
||||
});
|
||||
@@ -107,8 +131,7 @@ afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
// 全局 matchMedia mock(ThemeModeProvider 依赖)
|
||||
// 必须在 beforeEach 中设置,因为 afterEach 的 restoreAllMocks 会清除它
|
||||
// 全局 matchMedia 极客级环境模拟(ThemeModeProvider 依赖)
|
||||
beforeEach(() => {
|
||||
Object.defineProperty(window, 'matchMedia', {
|
||||
writable: true,
|
||||
|
||||
Reference in New Issue
Block a user