gpt4 book ai didi

c# - 使用 xUnit 测试 Controller

转载 作者:行者123 更新时间:2023-12-05 04:02:22 26 4
gpt4 key购买 nike

我有 webapi,它需要调用其他端点并获取数据。

我目前的代码如下

//http客户端实现

public interface IHttpClientFactory
{
HttpClient Create();
}

public class HttpClientFactory : IHttpClientFactory
{
private readonly ApplicationSettings _applicationSettings;
HttpClient _httpClient;

public HttpClientFactory(IOptions<ApplicationSettings> settings)
{
_applicationSettings = settings.Value;
}
public HttpClient Create()
{
if (_httpClient != null)
return _httpClient;

var client = new HttpClient()
{
BaseAddress = new Uri($"{_applicationSettings.BaseUrl}")
};
_httpClient = client;
return _httpClient;
}
}

public interface IGetItemsQuery
{
Task<IEnumerable<T>> Execute<T>(string url);
}

public class GetItemQuery: IGetItemsQuery
{
private readonly IHttpClientFactory _httpClientFactory;
public GetPhotosQuery(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}

public async Task<IEnumerable<T>> Execute<T>(string url)
{
using (var response = await _httpClientFactory.Create().GetAsync($"{url}").ConfigureAwait(false))
{
response.EnsureSuccessStatusCode();
var resp = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
var items = JArray.Parse(resp);
return items.ToObject<T[]>();
}
}

在我的 Controller 部分

   private readonly IGetItemsQuery _getItemsQuery;

public HomeController(IGetItemsQuery getItemsQuery)
{
_getItemsQuery = getItemsQuery;
}

appsettings

"ApplicationSettings": {
"BaseUrl": "http://someendpoint.com/"

启动

   services.Configure<ApplicationSettings>(Configuration.GetSection("ApplicationSettings"));
services.AddScoped<IGetItemsQuery, GetPhotosQuery>();
services.AddScoped<IHttpClientFactory, HttpClientFactory>();

我想在我的测试中尝试类似下面的东西

     [Fact]
public void Test_Index()
{
// Arrange
var itemsQuery = new Mock<IGetItemsQuery>();
var controller = new HomeController(itemsQuery.Object);

// Act
var result = controller.Index();

// Assert
var viewResult = Assert.IsType<ViewResult>(result);
Assert.Null(viewResult.ViewName);
}

这是在创建模拟 IGetItemsQuery,但这并不是在模拟实际的 IHttpClientFactory。

有没有办法做到这一点

最佳答案

根据具有抽象依赖项的设计,无需模拟客户端工厂即可对 Controller 进行单元测试。

正如您在测试中所做的那样,您模拟了 IGetItemsQuery,但是您没有将其设置为在测试中调用时按预期运行。

例如,如果被测 Controller 方法看起来像这样

private readonly IGetItemsQuery getItemsQuery;

public HomeController(IGetItemsQuery getItemsQuery) {
this.getItemsQuery = getItemsQuery;
}

public async Task<IActionResult> Index() {
var url = "....";

var items = await getItemsQuery.Execute<MyItem>(url);

return View(items);
}

然后作为被测方法的 Index 操作的独立单元测试可能类似于

[Fact]
public async Task Index_Should_Return_View_With_Items() {
// Arrange
var itemsQuery = new Mock<IGetItemsQuery>();

var items = new MyItem[] {
new MyItem(),
new MyItem()
};

itemsQuery.Setup(_ => _.Execute<MyItem>(It.IsAny<string>()))
.ReturnsAsync(items);

var controller = new HomeController(itemsQuery.Object);

// Act
var result = await controller.Index();

// Assert
var viewResult = Assert.IsType<ViewResult>(result);
Assert.Null(viewResult.ViewName);
}

关于c# - 使用 xUnit 测试 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54399357/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com