using Infrastructure.StockData; namespace Application.Tests; [TestClass] public sealed class KoreaEximRateParserTests { [TestMethod] public void Parse_ItemNameAndRate_MappedFromCandidateFields() { // 수출입은행 AP02/AP03 응답 골격 — 최상위 배열, 항목명은 cur_nm, 금리 수치는 후보 필드(deal_bas_r 등)에서 첫 성공값 const string json = """ [ {"result":1,"cur_nm":"리보 1개월","deal_bas_r":"4.5321"}, {"result":1,"cur_nm":"리보 3개월","deal_bas_r":"4.6789"} ] """; var rows = KoreaEximRateParser.Parse(json); Assert.AreEqual(2, rows.Count); Assert.AreEqual("리보 1개월", rows[0].ItemName); Assert.AreEqual(4.5321m, rows[0].Rate); Assert.AreEqual("리보 3개월", rows[1].ItemName); Assert.AreEqual(4.6789m, rows[1].Rate); } [TestMethod] public void Parse_ThousandsCommaStrippedAndFailedResultSkipped() { // 천단위 콤마 방어 + result != 1 행 skip const string json = """ [ {"result":4,"cur_nm":"일일제한초과행","deal_bas_r":"1.0000"}, {"result":1,"cur_nm":"우대금리","deal_bas_r":"1,234.5000"} ] """; var rows = KoreaEximRateParser.Parse(json); Assert.AreEqual(1, rows.Count, "result=4 행은 제외"); Assert.AreEqual("우대금리", rows[0].ItemName); Assert.AreEqual(1234.5000m, rows[0].Rate, "천단위 콤마 제거"); } [TestMethod] public void Parse_NoNumericField_KeepsItemWithNullRate() { // 수치 후보 필드가 전부 빈값/미제공이면 항목만 보존하고 Rate=null (0 과 구분) const string json = """ [ {"result":1,"cur_nm":"미고시항목","deal_bas_r":"","ttb":"-","tts":""} ] """; var rows = KoreaEximRateParser.Parse(json); Assert.AreEqual(1, rows.Count); Assert.AreEqual("미고시항목", rows[0].ItemName); Assert.IsNull(rows[0].Rate, "수치 없으면 null"); } [TestMethod] public void Parse_EmptyArrayOrBlank_ReturnsEmpty() { // 주말/공휴일·오전 이전 빈 배열, 빈 응답 → 0건 (예외 없음) Assert.AreEqual(0, KoreaEximRateParser.Parse("[]").Count); Assert.AreEqual(0, KoreaEximRateParser.Parse("").Count); Assert.AreEqual(0, KoreaEximRateParser.Parse("{}").Count, "배열이 아니면 0건"); } }