2 回答

TA貢獻1887條經驗 獲得超5個贊
所有使測試變慢的依賴項都應該被抽象出來。用抽象
包裹HttpClient起來,您可以在測試中模擬它。
public interface IMyClient
{
Task<string> GetRawDataFrom(string url);
}
那么你的控制器將依賴于那個抽象
public class DemoController : Controller
{
private readonly IMyClient _client;
private string _baseUrl = "http://localhost:90/webservice";
public DemoController(IMyClient client)
{
_client = client;
}
public async Task<ActionResult> Index()
{
var rawData = _client.GetRawDataFrom($"{_baseUrl}vehicle/menu/year");
using (var reader = new StringReader(rawData))
{
var result =
(MenuItems)new XmlSerializer(typeof(MenuItems)).Deserialize(reader);
return View("Index", result);
}
}
}
然后在測試中,您可以模擬您的抽象以返回預期數據
public class FakeClient : IMyClient
{
public string RawData { get; set; }
public Task<string> GetRawDataFrom(string url)
{
return Task.FromResult(RawData);
}
}
[TestMethod]
public async Task Test_Index()
{
// Arrange
var fakeClient = new FakeClient
{
RawData = @"[
{ Name: "One", Path: "/one" },
{ Name: "Two", Path: "/two" }
]"
};
DemoController controller = new DemoController(fakeClient);
// Act
var result = await controller.Index();
ViewResult viewResult = (ViewResult)result;
// Assert
Assert.AreEqual("Index", viewResult.ViewName);
Assert.IsNotNull(viewResult.Model);
}
實際實施將使用 HttpClient
public class MyHttpClient : IMyClient
{
public Task<string> GetRawDataFrom(string url)
{
var response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsStringAsync();
}
}
}

TA貢獻1859條經驗 獲得超6個贊
在HttpClient沒有服務包裝器、模擬或 IoC 容器的情況下測試調用的另一種方法是使用Flurl,這是一個小型包裝器庫HttpClient,提供(除其他外)一些強大的測試功能。[免責聲明:我是作者]
這是您的控制器的外觀。有幾種方法可以做到這一點,但這種方法使用字符串擴展方法來完全抽象出客戶端。(HttpClient為您管理每個主機的單個實例以防止出現問題。)
using Flurl.Http;
public class DemoController : Controller
{
string baseUrl = "http://localhost:90/webservice";
// GET: DemoInfo
public async Task<ActionResult> Index()
{
var content = await baseUrl
.AppendPathSegment("vehicle/menu/year")
.GetStringAsync();
var result = (MenuItems)new XmlSerializer(typeof(MenuItems)).Deserialize(new StringReader(content));
return View("Index", result);
}
}
和測試:
using Flurl.Http;
[TestMethod]
public async Task Test_Index()
{
// fake & record all HTTP calls in the test subject
using (var httpTest = new HttpTest())
{
// Arrange
httpTest.RespondWith(200, "<xml>some fake response xml...</xml>");
DemoController controller = new DemoController();
// Act
var result = await controller.Index();
ViewResult viewResult = (ViewResult) result;
// Assert
Assert.AreEqual("Index", viewResult.ViewName);
Assert.IsNotNull(viewResult.Model);
}
}
Flurl.Http 在NuGet上可用。
- 2 回答
- 0 關注
- 221 瀏覽
添加回答
舉報