marketDataManager.test.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. import { MarketDataManager, MarketData, Ticker24hr, KlineData, DepthData } from '../../src/market/marketDataManager'
  2. const describeMarket = process.env.TEST_MARKET === '1' ? describe : describe.skip
  3. // Mock WebSocket
  4. jest.mock('ws', () => {
  5. return jest.fn().mockImplementation(() => ({
  6. on: jest.fn(),
  7. send: jest.fn(),
  8. close: jest.fn(),
  9. ping: jest.fn(),
  10. }))
  11. })
  12. describeMarket('MarketDataManager', () => {
  13. let marketManager: MarketDataManager
  14. let mockWs: any
  15. beforeEach(() => {
  16. // 清除所有 Mock
  17. jest.clearAllMocks()
  18. // 创建 Mock WebSocket 实例
  19. const WebSocket = require('ws')
  20. mockWs = new WebSocket()
  21. marketManager = new MarketDataManager('wss://test.com/ws')
  22. })
  23. afterEach(() => {
  24. marketManager.disconnect()
  25. })
  26. describe('Constructor', () => {
  27. test('should create instance with default configuration', () => {
  28. const manager = new MarketDataManager()
  29. expect(manager).toBeInstanceOf(MarketDataManager)
  30. })
  31. test('should create instance with custom configuration', () => {
  32. const manager = new MarketDataManager('wss://custom.com/ws', 3000, 5)
  33. expect(manager).toBeInstanceOf(MarketDataManager)
  34. })
  35. })
  36. describe('Connection Management', () => {
  37. test('should connect to WebSocket', async () => {
  38. // Mock WebSocket open event
  39. mockWs.on.mockImplementation((event, callback) => {
  40. if (event === 'open') {
  41. setTimeout(() => callback(), 0)
  42. }
  43. })
  44. await marketManager.connect()
  45. expect(mockWs.on).toHaveBeenCalledWith('open', expect.any(Function))
  46. })
  47. test('should handle connection errors', async () => {
  48. const error = new Error('Connection failed')
  49. mockWs.on.mockImplementation((event, callback) => {
  50. if (event === 'error') {
  51. setTimeout(() => callback(error), 0)
  52. }
  53. })
  54. await expect(marketManager.connect()).rejects.toThrow('Connection failed')
  55. })
  56. test('should disconnect WebSocket', () => {
  57. marketManager.disconnect()
  58. expect(mockWs.close).toHaveBeenCalled()
  59. })
  60. })
  61. describe('Data Management', () => {
  62. test('should get market data', () => {
  63. const result = marketManager.getMarketData('BTCUSDT')
  64. expect(result).toBeNull() // 初始状态应该为空
  65. })
  66. test('should get all market data', () => {
  67. const result = marketManager.getAllMarketData()
  68. expect(result).toBeInstanceOf(Map)
  69. expect(result.size).toBe(0)
  70. })
  71. test('should get ticker 24hr data', () => {
  72. const result = marketManager.getTicker24hr('BTCUSDT')
  73. expect(result).toBeNull()
  74. })
  75. test('should get all ticker 24hr data', () => {
  76. const result = marketManager.getAllTicker24hr()
  77. expect(result).toBeInstanceOf(Map)
  78. expect(result.size).toBe(0)
  79. })
  80. test('should get kline data', () => {
  81. const result = marketManager.getKlineData('BTCUSDT', '1m', 10)
  82. expect(result).toEqual([])
  83. })
  84. test('should get depth data', () => {
  85. const result = marketManager.getDepthData('BTCUSDT')
  86. expect(result).toBeNull()
  87. })
  88. test('should get subscribed symbols', () => {
  89. const result = marketManager.getSubscribedSymbols()
  90. expect(result).toEqual([])
  91. })
  92. })
  93. describe('Subscription Management', () => {
  94. test('should subscribe to market data', () => {
  95. const symbols = ['BTCUSDT', 'ETHUSDT']
  96. const intervals = ['1m', '5m']
  97. // Mock connected state
  98. Object.defineProperty(marketManager, 'isConnected', {
  99. get: () => true,
  100. })
  101. marketManager.subscribeMarketData(symbols, intervals)
  102. expect(mockWs.send).toHaveBeenCalledWith(expect.stringContaining('"method":"SUBSCRIBE"'))
  103. })
  104. test('should unsubscribe from market data', () => {
  105. const symbols = ['BTCUSDT']
  106. // Mock connected state
  107. Object.defineProperty(marketManager, 'isConnected', {
  108. get: () => true,
  109. })
  110. marketManager.unsubscribeMarketData(symbols)
  111. expect(mockWs.send).toHaveBeenCalledWith(expect.stringContaining('"method":"UNSUBSCRIBE"'))
  112. })
  113. })
  114. describe('Connection Status', () => {
  115. test('should check connection status', () => {
  116. const result = marketManager.isConnectedToWebSocket()
  117. expect(typeof result).toBe('boolean')
  118. })
  119. })
  120. describe('Event Handling', () => {
  121. test('should emit connected event', done => {
  122. marketManager.on('connected', () => {
  123. done()
  124. })
  125. // Mock WebSocket open event
  126. mockWs.on.mockImplementation((event, callback) => {
  127. if (event === 'open') {
  128. callback()
  129. }
  130. })
  131. marketManager.connect()
  132. })
  133. test('should emit disconnected event', done => {
  134. marketManager.on('disconnected', (code, reason) => {
  135. expect(code).toBe(1000)
  136. expect(reason).toBe('Normal closure')
  137. done()
  138. })
  139. // Mock WebSocket close event
  140. mockWs.on.mockImplementation((event, callback) => {
  141. if (event === 'close') {
  142. callback(1000, Buffer.from('Normal closure'))
  143. }
  144. })
  145. marketManager.connect()
  146. })
  147. test('should emit error event', done => {
  148. const error = new Error('Test error')
  149. marketManager.on('error', err => {
  150. expect(err).toBe(error)
  151. done()
  152. })
  153. // Mock WebSocket error event
  154. mockWs.on.mockImplementation((event, callback) => {
  155. if (event === 'error') {
  156. callback(error)
  157. }
  158. })
  159. marketManager.connect()
  160. })
  161. })
  162. })