1
+ import { renderHook , act } from '@testing-library/react' ;
2
+ import useIndexDBState from '../index' ;
3
+
4
+ // 模拟 IndexedDB
5
+ const mockIndexedDB = {
6
+ open : jest . fn ( ) ,
7
+ } ;
8
+
9
+ const mockIDBOpenDBRequest = {
10
+ onerror : null ,
11
+ onsuccess : null ,
12
+ onupgradeneeded : null ,
13
+ result : {
14
+ transaction : jest . fn ( ) ,
15
+ close : jest . fn ( ) ,
16
+ objectStoreNames : {
17
+ contains : jest . fn ( ) . mockReturnValue ( false ) ,
18
+ } ,
19
+ createObjectStore : jest . fn ( ) ,
20
+ } ,
21
+ } ;
22
+
23
+ const mockObjectStore = {
24
+ get : jest . fn ( ) ,
25
+ put : jest . fn ( ) ,
26
+ delete : jest . fn ( ) ,
27
+ } ;
28
+
29
+ const mockTransaction = {
30
+ objectStore : jest . fn ( ) . mockReturnValue ( mockObjectStore ) ,
31
+ } ;
32
+
33
+ // 模拟 window.indexedDB
34
+ Object . defineProperty ( window , 'indexedDB' , {
35
+ value : mockIndexedDB ,
36
+ writable : true ,
37
+ } ) ;
38
+
39
+ describe ( 'useIndexDBState' , ( ) => {
40
+ beforeEach ( ( ) => {
41
+ // 设置全局 indexedDB 模拟
42
+ mockIndexedDB . open . mockReturnValue ( mockIDBOpenDBRequest ) ;
43
+ mockIDBOpenDBRequest . result . transaction . mockReturnValue ( mockTransaction ) ;
44
+
45
+ // 清除之前的模拟调用
46
+ jest . clearAllMocks ( ) ;
47
+ } ) ;
48
+
49
+ it ( 'should initialize with default value' , async ( ) => {
50
+ const { result } = renderHook ( ( ) =>
51
+ useIndexDBState ( 'test-key' , {
52
+ defaultValue : 'default value' ,
53
+ } ) ,
54
+ ) ;
55
+
56
+ expect ( result . current [ 0 ] ) . toBe ( 'default value' ) ;
57
+ } ) ;
58
+
59
+ it ( 'should update state when setState is called' , async ( ) => {
60
+ const { result } = renderHook ( ( ) =>
61
+ useIndexDBState ( 'test-key' , {
62
+ defaultValue : 'default value' ,
63
+ } ) ,
64
+ ) ;
65
+
66
+ act ( ( ) => {
67
+ result . current [ 1 ] ( 'new value' ) ;
68
+ } ) ;
69
+
70
+ expect ( result . current [ 0 ] ) . toBe ( 'new value' ) ;
71
+ } ) ;
72
+
73
+ it ( 'should handle function updater' , async ( ) => {
74
+ const { result } = renderHook ( ( ) =>
75
+ useIndexDBState ( 'test-key' , {
76
+ defaultValue : 'default value' ,
77
+ } ) ,
78
+ ) ;
79
+
80
+ act ( ( ) => {
81
+ result . current [ 1 ] ( ( prev ) => `${ prev } updated` ) ;
82
+ } ) ;
83
+
84
+ expect ( result . current [ 0 ] ) . toBe ( 'default value updated' ) ;
85
+ } ) ;
86
+
87
+ it ( 'should handle undefined value' , async ( ) => {
88
+ const { result } = renderHook ( ( ) =>
89
+ useIndexDBState ( 'test-key' , {
90
+ defaultValue : 'default value' ,
91
+ } ) ,
92
+ ) ;
93
+
94
+ act ( ( ) => {
95
+ result . current [ 1 ] ( undefined ) ;
96
+ } ) ;
97
+
98
+ expect ( result . current [ 0 ] ) . toBeUndefined ( ) ;
99
+ } ) ;
100
+
101
+ it ( 'should call onError when an error occurs' , async ( ) => {
102
+ const onError = jest . fn ( ) ;
103
+ mockIndexedDB . open . mockImplementationOnce ( ( ) => {
104
+ throw new Error ( 'Test error' ) ;
105
+ } ) ;
106
+
107
+ renderHook ( ( ) =>
108
+ useIndexDBState ( 'test-key' , {
109
+ defaultValue : 'default value' ,
110
+ onError,
111
+ } ) ,
112
+ ) ;
113
+
114
+ expect ( onError ) . toHaveBeenCalled ( ) ;
115
+ } ) ;
116
+ } ) ;
0 commit comments