【问题标题】:C#: Manually Create Filter Options in ODataC#:在 OData 中手动创建过滤器选项
【发布时间】:2020-09-10 18:17:17
【问题描述】:

我正在尝试在服务方法上手动创建 OData 查询。

如果可能,需要在 ODataQueryOptions 中创建变量。过滤器要求在示例中,Description = "Furniture"

http://localhost/odata/GetProductTypeDto()?$filter=Description eq 'Furniture'

代码:

public async Task<ProductTypeDto> GetProductTypeDto(ODataQueryOptions<ProductTypeDto> odataQueryOptions)
{
    var dto = (IQueryable<ProductTypeDto>)odataQueryOptions.ApplyTo(_productRepository.GetProductTypes)();
    var dtoList = await dto.ToListAsync();
    return dto;
}

_productRepository.GetProductTypes() = // IQueryable which brings out this result {
  new ProductTypeDto {ProductTypeId = 1, Description = "Furniture"},
  new ProductTypeDto {ProductTypeId = 2, Description = "Electronics"},
  new ProductTypeDto {ProductTypeId = 3, Description = "Books"}
}

我们现在尝试在变量 odataQueryOptions 中创建过滤器 Furniture,而不使用 API。

稍后尝试对某些内容进行单元测试,

var actualResult = product.GetProductTypeDto(odataQueryOptions)
Assert.Equals(actualResult.ProductTypeId, 1);
Assert.Equals(actualResult.Description, "Furniture");

【问题讨论】:

  • 还不清楚,你是问如何以编程方式(无API)将带有过滤器的URL构造为字符串?或者您是在询问如何对 OData 端点进行单元测试?

标签: c# .net asp.net-core .net-core odata


【解决方案1】:

更新

在这个领域很难找到 OData 的具体指导的原因之一是 URL 解析和 OData 反序列化(尤其是在 Patch 附近)是为我们管理或抽象出来的。这有好有坏,但这意味着孤立的传统 API 端点测试变得复杂。

例如,传统的 API 端点将具有离散的输入参数和离散的响应参数,但是 OData 参数通常包装在通用字典或帮助对象中,这些对象知道如何根据输入来操作查询,但很难手动检查。来自端点的响应通常也包装在一个通用的协商内容响应包装器

Units tests should focus on behaviour only

单元测试涉及独立于其基础架构和依赖项来测试应用程序的一部分。当您对控制器逻辑进行单元测试时,仅测试单个操作或方法的内容,而不是其依赖项或框架本身的行为。单元测试不会检测组件之间的交互问题——这是集成测试的目的。

对于 OData,$filter$select$expand... 等查询选项确实是框架的一部分,内容协商 和序列化也是如此。出于传统单元测试的目的,这些元素需要大量的努力和配置来模拟,以至于许多测试变得不确定,当它们通过或失败时,这与配置或您尝试的实际逻辑有关目标?

控制器上的 OData 端点通常更容易使用 integration testing 实践进行测试。特别是对于 OData,这意味着您必须运行实际服务的实例(在内存中,或部署在本地或特定的测试环境中),以便您可以评估端点以及它们如何通过 HTTP 管道评估查询消息。

您可以在 VS 中自动执行此操作,或者分两步完成,将您的 API 部署到具有准备好的数据库的测试位置,然后针对它执行测试脚本,可以作为 VS 单元测试,也可以使用 Postman 等外部工具。

  • 有一些 NuGet 包可以帮助此过程,但可以通过编程方式“self host”您的 API,因此您可以在单元测试初始化​​过程中连接它。


这些原因使直接针对 OData 端点方法的单元测试变得复杂:

  • 大部分投影逻辑 ($select/$expand) 由 EnableQueryAttribute 评估
  • 要构造 ODataQueryOptions 的实例,需要构造并传入 EdmModel 以及要操作的 Http 请求。

因此,设置模拟的 QueryOptions 所需的工作量几乎与仅运行服务实例的工作量相同。

如果您的测试例程需要特定且复杂的手动配置,基本上几乎完全重新创建 API 环境,那么当测试失败时,错误的测试结果(正面和负面)的风险很高,这是否意味着测试的设置有问题或您正在测试的生产代码有问题?

有些人在这方面取得了成功,看看 OData 项目论坛中的这篇文章: [feature/netcore] How to unit test with ODataQueryOptions #1352

也请查看此指南,尽管它不太适合您的需求:
Unit test controller logic in ASP.NET Core

【讨论】:

  • 可以通过内存、单元类型测试环境运行api http测试吗?
  • 是的,您可以很容易地做到这一点,这是迁移到 OWIN 管道而不是依赖 IIS 作为主机的结果之一。我已经更新了我的答案以包含更多推理,SO 中的这篇文章将特别有助于自我托管:stackoverflow.com/q/30298458/1690217
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-09
  • 1970-01-01
  • 2011-02-04
  • 1970-01-01
相关资源
最近更新 更多