【问题标题】:Instantiate new System.Web.Http.OData.Query.ODataQueryOptions in nunit test of ASP.NET Web API controller在 ASP.NET Web API 控制器的 nunit 测试中实例化新的 System.Web.Http.OData.Query.ODataQueryOptions
【发布时间】: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不提供见解(什么实现了该接口?)。

我需要做什么/有更好的方法吗?

谢谢。

【问题讨论】:

    标签: asp.net-web-api nunit moq odata


    【解决方案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);
    }
    

    【讨论】:

      猜你喜欢
      • 2015-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-14
      • 1970-01-01
      相关资源
      最近更新 更多