在 ASP.NET Web API 控制器的 nunit 测试中实例化新的 System.Web.Http.OData.Query.ODataQueryOptions
Posted
技术标签:
【中文标题】在 ASP.NET Web API 控制器的 nunit 测试中实例化新的 System.Web.Http.OData.Query.ODataQueryOptions【英文标题】:Instantiate new System.Web.Http.OData.Query.ODataQueryOptions in nunit test of ASP.NET Web API controller 【发布时间】:2013-07-02 21:07:35 【问题描述】:我有一个带有 ApiController 继承控制器的 ASP.NET MVC4 Web API 项目,该控制器接受 ODataQueryOptions 参数作为其输入之一。
我正在使用 NUnit 和 Moq 来测试项目,这允许我从 ApiController 使用的相关存储库方法设置预设响应。这有效,如下所示:
[TestFixture]
public class ProjectControllerTests
[Test]
public async Task GetById()
var repo = new Mock<IManagementQuery>();
repo.Setup(a => a.GetProjectById(2)).Returns(Task.FromResult<Project>(new Project()
ProjectID = 2, ProjectName = "Test project", ProjectClient = 3
));
var controller = new ProjectController(repo.Object);
var response = await controller.Get(2);
Assert.AreEqual(response.id, 2);
Assert.AreEqual(response.name, "Test project");
Assert.AreEqual(response.clientId, 3);
我面临的挑战是,要使用这种模式,我需要将相关的查询字符串参数传递给控制器以及存储库(这实际上是我的意图)。但是,在接受 ODataQueryOptions 的 ApiController 方法的情况下,即使在我只想使用 ODataQueryOptions 的默认参数的情况下,我也需要知道如何实例化一个。这变得很棘手:
ODataQueryOptions 没有实现接口,所以无法直接模拟。 构造函数需要一个 System.Web.Http.OData.ODataQueryContext 的实现,这需要一个实现 Microsoft.Data.Edm.IEdmModel 的东西的实现,文档很少,Visual Studio 2012 Find References and View Call Hierarchy不提供见解(什么实现了该接口?)。我需要做什么/有更好的方法吗?
谢谢。
【问题讨论】:
【参考方案1】:看起来其他人已经在 cmets here 中回答了这个问题,但这不是我的用例的完整解决方案(见下面的评论):
ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<Customer>("Customers");
var opts = new ODataQueryOptions<Customer>(new ODataQueryContext(modelBuilder.GetEdmModel(),typeof(Customer)), request);
【讨论】:
好吧,由于我的 EntitySet 是从 EntityFramework 模型派生的,而且它们在很大程度上是相关的对象,看来我需要为我的 objectcontext 中的每个 TEntity 提供一个 EntitySet ......这是真的吗?必须有一种方法可以从 objectcontext => odataqueryoptions 出发,对吧?【参考方案2】:这是我在 NUnit 测试中用于注入 ODataQueryOptions 的解决方案
private static IEdmModel _model;
private static IEdmModel Model
get
if (_model == null)
var builder = new ODataConventionModelBuilder();
var baseType = typeof(MyDbContext);
var sets = baseType.GetProperties().Where(c => c.PropertyType.IsGenericType && c.PropertyType.GetGenericTypeDefinition() == typeof(IDbSet<>));
var entitySetMethod = builder.GetType().GetMethod("EntitySet");
foreach (var set in sets)
var genericMethod = entitySetMethod.MakeGenericMethod(set.PropertyType.GetGenericArguments());
genericMethod.Invoke(builder, new object[] set.Name );
_model = builder.GetEdmModel();
return _model;
public static ODataQueryOptions<T> QueryOptions<T>(string query = null)
query = query ?? "";
var url = "http://localhost/Test?" + query;
var request = new HttpRequestMessage(HttpMethod.Get, url);
return new ODataQueryOptions<T>(new ODataQueryContext(Model, typeof(T)), request);
【讨论】:
以上是关于在 ASP.NET Web API 控制器的 nunit 测试中实例化新的 System.Web.Http.OData.Query.ODataQueryOptions的主要内容,如果未能解决你的问题,请参考以下文章
如何在 ASP.NET Web API 中指定控制器的名称?