| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- using Infrastructure.StockData;
- namespace Application.Tests;
- [TestClass]
- public sealed class DataGoKrParserTests
- {
- [TestMethod]
- public void ParseDailyPrices_MapsFields_FromSampleJson()
- {
- // 금융위 주식시세정보(getStockPriceInfo) 표준 응답 샘플 — 실호출 불가 전제의 고정 문자열 검증
- const string json = """
- {"response":{"header":{"resultCode":"00","resultMsg":"NORMAL SERVICE."},"body":{"numOfRows":2,"pageNo":1,"totalCount":2,"items":{"item":[
- {"basDt":"20260702","srtnCd":"005930","isinCd":"KR7005930003","itmsNm":"삼성전자","mrktCtg":"KOSPI","clpr":"70500","vs":"-500","fltRt":"-.70","mkp":"71000","hipr":"71200","lopr":"70300","trqu":"12345678","trPrc":"870000000000","lstgStCnt":"5969782550","mrktTotAmt":"420870169275000"},
- {"basDt":"20260702","srtnCd":"A000660","isinCd":"KR7000660001","itmsNm":"SK하이닉스","mrktCtg":"KOSPI","clpr":"210000","vs":"3000","fltRt":"1.45","mkp":"208000","hipr":"211500","lopr":"207000","trqu":"2345678","trPrc":"490000000000","lstgStCnt":"728002365","mrktTotAmt":"152880496650000"}
- ]}}}}
- """;
- var (items, totalCount) = DataGoKrStockParser.ParseDailyPrices(json);
- Assert.AreEqual(2, totalCount);
- Assert.AreEqual(2, items.Count);
- var samsung = items[0];
- Assert.AreEqual("005930", samsung.Code);
- Assert.AreEqual(new DateOnly(2026, 7, 2), samsung.TradingDate);
- Assert.AreEqual(71000, samsung.Open);
- Assert.AreEqual(71200, samsung.High);
- Assert.AreEqual(70300, samsung.Low);
- Assert.AreEqual(70500, samsung.Close);
- Assert.AreEqual(12345678L, samsung.Volume);
- Assert.AreEqual(870000000000L, samsung.TradingValue);
- Assert.AreEqual(-500, samsung.ChangeAmount);
- Assert.AreEqual(-0.70m, samsung.ChangeRate, "-.70 형식 등락률을 파싱해야 한다");
- Assert.AreEqual(420870169275000L, samsung.MarketCap);
- Assert.AreEqual(5969782550L, samsung.ListedShares);
- Assert.AreEqual("000660", items[1].Code, "'A' 프리픽스 단축코드는 뒤 6자리로 정규화한다");
- }
- [TestMethod]
- public void ParseListedItems_SingleObjectItem_AndEmptyItems()
- {
- // 단건 응답은 item 이 배열이 아닌 객체로 온다
- const string single = """
- {"response":{"header":{"resultCode":"00","resultMsg":"NORMAL SERVICE."},"body":{"numOfRows":1,"pageNo":1,"totalCount":1,"items":{"item":
- {"basDt":"20260702","srtnCd":"005930","isinCd":"KR7005930003","itmsNm":"삼성전자","mrktCtg":"KOSPI","crno":"1301110006246","corpNm":"삼성전자(주)"}
- }}}}
- """;
- var (items, totalCount) = DataGoKrStockParser.ParseListedItems(single);
- Assert.AreEqual(1, totalCount);
- Assert.AreEqual(1, items.Count);
- Assert.AreEqual("005930", items[0].Code);
- Assert.AreEqual("KR7005930003", items[0].Isin);
- Assert.AreEqual("삼성전자", items[0].Name);
- Assert.AreEqual("KOSPI", items[0].MarketName);
- Assert.AreEqual(new DateOnly(2026, 7, 2), items[0].BaseDate);
- // 0건이면 items 가 빈 문자열로 온다
- const string empty = """
- {"response":{"header":{"resultCode":"00","resultMsg":"NORMAL SERVICE."},"body":{"numOfRows":0,"pageNo":1,"totalCount":0,"items":""}}}
- """;
- var (emptyItems, emptyTotal) = DataGoKrStockParser.ParseListedItems(empty);
- Assert.AreEqual(0, emptyTotal);
- Assert.AreEqual(0, emptyItems.Count);
- }
- [TestMethod]
- public void Parse_ErrorResultCode_Throws()
- {
- // 게이트웨이 정상 + 서비스 오류 코드 응답은 예외로 표면화한다 (조용한 빈 수집 방지)
- const string error = """
- {"response":{"header":{"resultCode":"30","resultMsg":"SERVICE_KEY_IS_NOT_REGISTERED_ERROR"},"body":null}}
- """;
- Assert.ThrowsExactly<InvalidOperationException>(() => DataGoKrStockParser.ParseListedItems(error));
- }
- }
|