單元測試-元大0050API 為例,大量多筆假資料產生

單元測試

最近在測試部分功能,遇到第三方API或是資料量需要更多假資料的時候,不就要刻到死嗎?

 


後來想到一招,我先產生資源檔案,在讀取資源檔案直接抓資源檔的json轉換假資料,同樣的如果是要隔離DB的時候,我也是有可能考慮用這樣方式,因為比較靠近需求面的資料...

沿用上一個例子去調整,因為有測試的緣故下,其實重構的問題,追加功能就沒這麼大壓力啦!

    public interface IHttpClientProvider
    {
        void LineNotifyToken();
        HttpResponseMessage Get(string requestUri);
        HttpResponseMessage Post(string requestUri, FormUrlEncodedContent content);
    }

Interface部分追加一個Get來調用元大0050的API成分股

    public class HttpClientProvider : IHttpClientProvider
    {
        private readonly HttpClient _httpClinet;

        public HttpClientProvider(HttpClient httpClinet)
        {
            _httpClinet = httpClinet;
        }
        public void LineNotifyToken() 
        {
            _httpClinet.DefaultRequestHeaders.Add("Authorization",
             "Bearer " + CommEnvironment.LineToken);
        }
        public HttpResponseMessage Get(string request)
        {
            return _httpClinet.GetAsync(request).Result;
        }
        public HttpResponseMessage Post(string request, FormUrlEncodedContent content)
        {
            return _httpClinet.PostAsync(request, content).Result;
        }
    }

最後在定義出元大的50公司資訊ViewModel

​
    public class Tainwan50ComapnyInfoViewModel
    {
        public string code { get; set; }
        public object ym { get; set; }
        public string name { get; set; }
        public string ename { get; set; }
        public double weights { get; set; }
        public double qty { get; set; }
    }

​

 

    public class StockServicea
    {
        private readonly IHttpClientProvider _httpClientProvider;

        public StockServicea(IHttpClientProvider httpClientProvider)
        {
            _httpClientProvider = httpClientProvider;
        }
        public List<Tainwan50ComapnyInfoViewModel> GetTaiwan50List()
        {
            try
            {
                var response = _httpClientProvider.Get(CommEnvironment.Taiwan0050ApiUrl);
                if (response.IsSuccessStatusCode)
                {
                   string responseBody = response.Content.ReadAsStringAsync().Result;
                   var result = JsonSerializer.Deserialize<List<Tainwan50ComapnyInfoViewModel>>(responseBody);
                   return result;
                }
            }
            catch (HttpRequestException e)
            {
               Console.WriteLine(e.Message);
            }
            return null;
        }
    }

加入資源檔案,把Json內容,放置文字檔案裏面

 


 

    public class StockServiceTest
    {
        private IHttpClientProvider _httpClientProvider;
        private string _taiwan50CompanyInfo;
       
        [SetUp]
        public void Setup()
        {
            _httpClientProvider = Substitute.For<IHttpClientProvider>();
            //抓取資源檔
            _taiwan50CompanyInfo = Properties.StockResources.Tainwan50CompanyInfo;
        }
        [Test]
        public void GetTaiwan50List_Ok_ReturnCompanyInfo()
        {
            HttpContent content = new StringContent(_taiwan50CompanyInfo);
            var expectedResponse = new HttpResponseMessage { StatusCode = HttpStatusCode.OK, Content = content };
            _httpClientProvider.Get(Arg.Any<string>()).Returns(expectedResponse);
            StockService stockService = new StockService(_httpClientProvider);
            var result = stockService.GetTaiwan50List();
            Assert.AreEqual(50,result.Count);
        }
        [Test]
        public void GetTaiwan50List_BadRequest_ReturnNull()
        {
            var expectedResponse = new HttpResponseMessage { StatusCode = HttpStatusCode.BadRequest};
            _httpClientProvider.Get(Arg.Any<string>()).Returns(expectedResponse);
            StockService stockService = new StockService(_httpClientProvider);
            var result = stockService.GetTaiwan50List();
            Assert.AreEqual(null, result);
        }
    }

這樣我也省下自己大量自己刻資料...

另外一種做法是...已經有自己第三方元件方式,不過這一部分還是滿合適用在API或是Repository依照情境不同去調用!

這個範例其實已經簡化過啦...這個功能在現有專案一堆邏輯在做...

元哥的筆記