單元測試
最近在測試部分功能,遇到第三方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依照情境不同去調用!
這個範例其實已經簡化過啦...這個功能在現有專案一堆邏輯在做...
元哥的筆記