From d32a30e91ac89f3e02d3cbc9bb2df6278b904094 Mon Sep 17 00:00:00 2001 From: anjdydhody Date: Mon, 2 Dec 2024 21:04:41 +0900 Subject: [PATCH 1/3] =?UTF-8?q?=E2=9C=85=20test:=20=EB=A7=A4=EC=88=98/?= =?UTF-8?q?=EB=A7=A4=EB=8F=84=20=EA=B0=80=EB=8A=A5=20=EC=88=98=EB=9F=89=20?= =?UTF-8?q?=EB=B0=8F=20=EA=B8=88=EC=95=A1=20=EC=A1=B0=ED=9A=8C=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80=20#237?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BE/src/asset/asset-service.spec.ts | 106 +++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 BE/src/asset/asset-service.spec.ts diff --git a/BE/src/asset/asset-service.spec.ts b/BE/src/asset/asset-service.spec.ts new file mode 100644 index 0000000..e7cdd9a --- /dev/null +++ b/BE/src/asset/asset-service.spec.ts @@ -0,0 +1,106 @@ +import { Test } from '@nestjs/testing'; +import { AssetService } from './asset.service'; +import { UserStockRepository } from './user-stock.repository'; +import { AssetRepository } from './asset.repository'; +import { StockDetailService } from '../stock/detail/stock-detail.service'; +import { StockPriceSocketService } from '../stockSocket/stock-price-socket.service'; +import { TradeType } from '../stock/order/enum/trade-type'; +import { StatusType } from '../stock/order/enum/status-type'; + +describe('asset test', () => { + let assetService: AssetService; + let userStockRepository: UserStockRepository; + let assetRepository: AssetRepository; + let stockDetailService: StockDetailService; + let stockPriceSocketService: StockPriceSocketService; + + beforeEach(async () => { + const mockUserStockRepository = { findOneBy: jest.fn() }; + const mockAssetRepository = { + findAllPendingOrders: jest.fn(), + findOneBy: jest.fn(), + }; + const mockStockDetailService = {}; + const mockStockPriceSocketService = {}; + + const module = await Test.createTestingModule({ + providers: [ + AssetService, + { provide: UserStockRepository, useValue: mockUserStockRepository }, + { provide: AssetRepository, useValue: mockAssetRepository }, + { + provide: StockDetailService, + useValue: mockStockDetailService, + }, + { + provide: StockPriceSocketService, + useValue: mockStockPriceSocketService, + }, + ], + }).compile(); + + assetService = module.get(AssetService); + userStockRepository = module.get(UserStockRepository); + assetRepository = module.get(AssetRepository); + stockDetailService = module.get(StockDetailService); + stockPriceSocketService = module.get(StockPriceSocketService); + }); + + it('보유 주식과 미체결 주문을 모두 반영한 매도 가능 주식 수를 반환한다.', async () => { + jest.spyOn(userStockRepository, 'findOneBy').mockResolvedValue({ + id: 1, + user_id: 1, + stock_code: '005930', + quantity: 1, + avg_price: 1000, + last_updated: new Date(), + }); + + jest.spyOn(assetRepository, 'findAllPendingOrders').mockResolvedValue([ + { + id: 1, + user_id: 1, + stock_code: '005930', + trade_type: TradeType.SELL, + amount: 1, + price: 1000, + status: StatusType.PENDING, + created_at: new Date(), + }, + ]); + + expect(await assetService.getUserStockByCode(1, '005930')).toEqual({ + quantity: 0, + avg_price: 1000, + }); + }); + + it('보유 자산과 미체결 주문을 모두 반영한 매수 가능 금액을 반환한다.', async () => { + jest.spyOn(assetRepository, 'findOneBy').mockResolvedValue({ + id: 1, + user_id: 1, + stock_balance: 0, + cash_balance: 1000, + total_asset: 1000, + total_profit: 0, + total_profit_rate: 0, + }); + + jest.spyOn(assetRepository, 'findAllPendingOrders').mockResolvedValue([ + { + id: 1, + user_id: 1, + stock_code: '005930', + trade_type: TradeType.BUY, + amount: 1, + price: 1000, + status: StatusType.PENDING, + created_at: new Date(), + }, + ]); + + expect(await assetService.getCashBalance(1)).toEqual({ + cash_balance: 0, + }); + }); +}); From bdedb24a309adf87f4818aac3befb1d015a1b021 Mon Sep 17 00:00:00 2001 From: anjdydhody Date: Mon, 2 Dec 2024 21:56:08 +0900 Subject: [PATCH 2/3] =?UTF-8?q?=E2=9C=85=20test:=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=A1=B0=ED=9A=8C=20API=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1=20#237?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BE/src/asset/asset-service.spec.ts | 106 ++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 3 deletions(-) diff --git a/BE/src/asset/asset-service.spec.ts b/BE/src/asset/asset-service.spec.ts index e7cdd9a..96c165e 100644 --- a/BE/src/asset/asset-service.spec.ts +++ b/BE/src/asset/asset-service.spec.ts @@ -1,4 +1,6 @@ import { Test } from '@nestjs/testing'; +import { ApiProperty } from '@nestjs/swagger'; +import { DeepPartial } from 'typeorm'; import { AssetService } from './asset.service'; import { UserStockRepository } from './user-stock.repository'; import { AssetRepository } from './asset.repository'; @@ -6,6 +8,10 @@ import { StockDetailService } from '../stock/detail/stock-detail.service'; import { StockPriceSocketService } from '../stockSocket/stock-price-socket.service'; import { TradeType } from '../stock/order/enum/trade-type'; import { StatusType } from '../stock/order/enum/status-type'; +import { Asset } from './asset.entity'; +import { AssetResponseDto } from './dto/asset-response.dto'; +import { StockElementResponseDto } from './dto/stock-element-response.dto'; +import { MypageResponseDto } from './dto/mypage-response.dto'; describe('asset test', () => { let assetService: AssetService; @@ -15,13 +21,19 @@ describe('asset test', () => { let stockPriceSocketService: StockPriceSocketService; beforeEach(async () => { - const mockUserStockRepository = { findOneBy: jest.fn() }; + const mockUserStockRepository = { + findOneBy: jest.fn(), + findUserStockWithNameByUserId: jest.fn(), + findAllDistinctCode: jest.fn(), + find: jest.fn(), + }; const mockAssetRepository = { findAllPendingOrders: jest.fn(), findOneBy: jest.fn(), + save: jest.fn(), }; - const mockStockDetailService = {}; - const mockStockPriceSocketService = {}; + const mockStockDetailService = { getInquirePrice: jest.fn() }; + const mockStockPriceSocketService = { subscribeByCode: jest.fn() }; const module = await Test.createTestingModule({ providers: [ @@ -103,4 +115,92 @@ describe('asset test', () => { cash_balance: 0, }); }); + + it('마이페이지 조회 시 종목의 현재가를 반영한 총 자산을 반환한다.', async () => { + jest + .spyOn(userStockRepository, 'findUserStockWithNameByUserId') + .mockResolvedValue([ + { + user_stocks_id: 1, + user_stocks_user_id: 1, + user_stocks_stock_code: '005930', + user_stocks_quantity: 1, + user_stocks_avg_price: '1000', + user_stocks_last_updated: new Date(), + stocks_code: '005930', + stocks_name: '삼성전자', + stocks_market: 'KOSPI', + }, + ]); + + jest.spyOn(assetRepository, 'findOneBy').mockResolvedValue({ + id: 1, + user_id: 1, + stock_balance: 0, + cash_balance: 1000, + total_asset: 1000, + total_profit: 0, + total_profit_rate: 0, + }); + + jest + .spyOn(userStockRepository, 'findAllDistinctCode') + .mockResolvedValue([{ stock_code: '005930' }]); + + jest.spyOn(stockDetailService, 'getInquirePrice').mockResolvedValue({ + hts_kor_isnm: '삼성전자', + stck_shrn_iscd: '005930', + stck_prpr: '53600', + prdy_vrss: '-600', + prdy_vrss_sign: '5', + prdy_ctrt: '-1.11', + hts_avls: '3199803', + per: '25.15', + stck_mxpr: '70400', + stck_llam: '38000', + is_bookmarked: false, + }); + + jest.spyOn(userStockRepository, 'find').mockResolvedValue([ + { + id: 1, + user_id: 1, + stock_code: '005930', + quantity: 1, + avg_price: 1000, + last_updated: new Date(), + }, + ]); + + jest + .spyOn(assetRepository, 'save') + .mockImplementation((updatedAsset) => + Promise.resolve(updatedAsset as DeepPartial & Asset), + ); + + const assetResponse = new AssetResponseDto( + 1000, + 53600, + 54600, + -9945400, + '-99.45', + false, + ); + const stockElementResponse = new StockElementResponseDto( + '삼성전자', + '005930', + 1, + 1000, + '53600', + '-600', + '5', + '-1.11', + ); + + const expected = new MypageResponseDto(); + expected.asset = assetResponse; + expected.stocks = [stockElementResponse]; + + expect(await assetService.getMyPage(1)).toEqual(expected); + }); }); From 1da593874ee9c3610659b31b7a754d330d49bf93 Mon Sep 17 00:00:00 2001 From: anjdydhody Date: Mon, 2 Dec 2024 22:01:12 +0900 Subject: [PATCH 3/3] =?UTF-8?q?=F0=9F=94=A7=20=EB=A6=B0=ED=8A=B8=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=ED=95=B4=EA=B2=B0=20#237?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BE/src/asset/asset-service.spec.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/BE/src/asset/asset-service.spec.ts b/BE/src/asset/asset-service.spec.ts index 96c165e..719ae27 100644 --- a/BE/src/asset/asset-service.spec.ts +++ b/BE/src/asset/asset-service.spec.ts @@ -1,5 +1,4 @@ import { Test } from '@nestjs/testing'; -import { ApiProperty } from '@nestjs/swagger'; import { DeepPartial } from 'typeorm'; import { AssetService } from './asset.service'; import { UserStockRepository } from './user-stock.repository'; @@ -18,7 +17,6 @@ describe('asset test', () => { let userStockRepository: UserStockRepository; let assetRepository: AssetRepository; let stockDetailService: StockDetailService; - let stockPriceSocketService: StockPriceSocketService; beforeEach(async () => { const mockUserStockRepository = { @@ -55,7 +53,6 @@ describe('asset test', () => { userStockRepository = module.get(UserStockRepository); assetRepository = module.get(AssetRepository); stockDetailService = module.get(StockDetailService); - stockPriceSocketService = module.get(StockPriceSocketService); }); it('보유 주식과 미체결 주문을 모두 반영한 매도 가능 주식 수를 반환한다.', async () => {