2013-07-04 26 views
11

Tôi có dự án API Web MVC4 ASP.NET với bộ điều khiển kế thừa ApiController chấp nhận tham số ODataQueryOptions là một trong đầu vào của nó.Khởi tạo System.Web.Http.OData.Query.ODataQueryOptions mới trong thử nghiệm nunit của bộ điều khiển ASP.NET Web API

Tôi đang sử dụng NUnit và Moq để kiểm tra dự án, cho phép tôi thiết lập câu trả lời soạn trước từ các phương pháp lưu trữ liên quan được ApiController sử dụng. Công trình này, như trong:

[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); 
    } 
} 

Thách thức tôi có là, sử dụng mô hình này, tôi cần phải vượt qua trong các thông số chuỗi truy vấn liên quan đến việc điều khiển cũng như kho lưu trữ (điều này thực sự là ý định của tôi). Tuy nhiên, trong trường hợp của các phương thức ApiController chấp nhận ODataQueryOptions, ngay cả trong các trường hợp mà tôi muốn chỉ sử dụng các tham số mặc định cho ODataQueryOptions, tôi cần phải biết làm thế nào để khởi tạo một phương thức. Điều này trở nên phức tạp:

  • ODataQueryOptions không triển khai giao diện, vì vậy tôi không thể giả mạo trực tiếp.
  • Nhà xây dựng yêu cầu triển khai System.Web.Http.OData.ODataQueryContext, yêu cầu triển khai thực hiện một cái gì đó triển khai Microsoft.Data.Edm.IEdmModel, tài liệu khan hiếm và Visual Studio 2012 Tìm tài liệu tham khảo và Xem phân cấp cuộc gọi không cung cấp cái nhìn sâu sắc (những gì thực hiện giao diện đó?).

Tôi cần làm gì/Có cách nào tốt hơn để thực hiện việc này?

Cảm ơn.

Trả lời

6

Hình như người nào khác đã trả lời này trong các ý kiến ​​here, nhưng nó không phải là một giải pháp hoàn chỉnh cho việc sử dụng hợp cụ thể của tôi (xem bình luận dưới đây):

ODataModelBuilder modelBuilder = new ODataConventionModelBuilder(); 
modelBuilder.EntitySet<Customer>("Customers"); 
var opts = new ODataQueryOptions<Customer>(new ODataQueryContext(modelBuilder.GetEdmModel(),typeof(Customer)), request); 
+2

Vâng, kể từ EntitySet tôi có nguồn gốc từ một mô hình EntityFramework, và họ là những đối tượng chủ yếu có liên quan, có vẻ như tôi cần phải cung cấp một EntitySet <> cho mỗi TEntity trong ObjectContext của tôi ... điều này có đúng không? Có phải là một cách để đi từ objectcontext => odataqueryoptions, phải không? – user483679

0

Đây là giải pháp tôi đã được sử dụng trong tôi NUnit xét nghiệm để tiêm 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); 
} 
Các vấn đề liên quan