Asp.net mvc Web API、OData、$inlinecount和测试
我以前有一个Web API控制器,看起来像这样:Asp.net mvc Web API、OData、$inlinecount和测试,asp.net-mvc,asp.net-web-api,odata,Asp.net Mvc,Asp.net Web Api,Odata,我以前有一个Web API控制器,看起来像这样: public IQueryable<ApiDesignOverview> GetList( string brandIds = "", string categoryIds = "", string query = "", string categoryOp = "or") public PageResult<ApiDesignOverview
public IQueryable<ApiDesignOverview> GetList(
string brandIds = "",
string categoryIds = "",
string query = "",
string categoryOp = "or")
public PageResult<ApiDesignOverview> GetList(
ODataQueryOptions<ApiDesignOverview> options,
string brandIds = "",
string categoryIds = "",
string query = "",
string categoryOp = "or")
public IQueryable-我不想大量使用OData,因为这需要对应用程序进行大量的重新架构,所以我选择了PageResult
选项
现在我的控制器看起来像这样:
public IQueryable<ApiDesignOverview> GetList(
string brandIds = "",
string categoryIds = "",
string query = "",
string categoryOp = "or")
public PageResult<ApiDesignOverview> GetList(
ODataQueryOptions<ApiDesignOverview> options,
string brandIds = "",
string categoryIds = "",
string query = "",
string categoryOp = "or")
publicpageresult GetList(
ODataQueryOptions选项,
字符串brandIds=“”,
字符串categoryId=“”,
字符串查询=”,
字符串categoryOp=“或”)
我现在的问题是:
- 如何模拟用于单元测试的ODataQueryOptions李>
- 如果他们不能被嘲笑,我如何创造一个呢?我需要一个
ODataQueryContext
来构造一个,它需要一个Microsoft.Data.Edm.iedmodel
,它需要。。。什么?我找不到这方面的任何文档
真的,如果我能像以前一样从控制器签名中删除ODataQueryOptions,那就更好了。这可能吗?如果您希望返回IQueryable,但又希望获得$inlinecount的支持,那么仍然可以通过修改QueryableAttribute来实现这一点
public class InlineCountQueryableAttribute : QueryableAttribute
{
private static MethodInfo _createPageResult =
typeof(InlineCountQueryableAttribute)
.GetMethods(BindingFlags.Static | BindingFlags.NonPublic)
.Single(m => m.Name == "CreatePageResult");
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
base.OnActionExecuted(actionExecutedContext);
HttpRequestMessage request = actionExecutedContext.Request;
HttpResponseMessage response = actionExecutedContext.Response;
IQueryable result;
if (response.IsSuccessStatusCode
&& response.TryGetContentValue<IQueryable>(out result))
{
long? inlineCount = request.GetInlineCount();
if (inlineCount != null)
{
actionExecutedContext.Response = _createPageResult.MakeGenericMethod(result.ElementType).Invoke(
null, new object[] { request, request.GetInlineCount(), request.GetNextPageLink(), result }) as HttpResponseMessage;
}
}
}
internal static HttpResponseMessage CreatePageResult<T>(HttpRequestMessage request, long? count, Uri nextpageLink, IEnumerable<T> results)
{
return request.CreateResponse(HttpStatusCode.OK, new PageResult<T>(results, nextpageLink, count));
}
}
公共类InlineCountQueryableAttribute:QueryableAttribute
{
私有静态方法信息\u createPageResult=
类型(InlineCountQueryableAttribute)
.GetMethods(BindingFlags.Static | BindingFlags.NonPublic)
.Single(m=>m.Name==“CreatePageResult”);
公共覆盖无效OnActionExecuted(HttpActionExecuteContext ActionExecuteContext)
{
base.OnActionExecuted(actionExecutedContext);
HttpRequestMessage request=ActionExecuteContext.request;
HttpResponseMessage response=actionExecutedContext.response;
可预测的结果;
如果(response.issusccessstatuscode
&&响应.TryGetContentValue(输出结果))
{
long?inlineCount=request.GetInlineCount();
if(inlineCount!=null)
{
actionExecutedContext.Response=\u createPageResult.MakeGenericMethod(result.ElementType).Invoke(
null,新对象[]{request,request.GetInlineCount(),request.GetNextPageLink(),result})作为HttpResponseMessage;
}
}
}
内部静态HttpResponseMessage CreatePageResult(HttpRequestMessage请求、长计数、Uri下一步消息链接、IEnumerable结果)
{
return request.CreateResponse(HttpStatusCode.OK,new PageResult(results,nextpageLink,count));
}
}
请注意,我正在使用反射创建PageResult。您可以返回您喜欢的对象,该对象可以由您使用的格式化程序进行格式化。如果您使用Json格式化程序,带有结果和计数的匿名对象也可以使用。如果您不想(或不能像我的情况那样)改变使用ODataQueryOptions和PageResult的方式,下面是如何为单元测试创建ODataQueryOptions实例:
//arrange
var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/MyProject/api/Customers?$filter=CustomerID eq 1");
var controller = new CustomersController
{
Request = request
};
ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<Customer>("Customers");
var opts = new ODataQueryOptions<Customer>(new ODataQueryContext(modelBuilder.GetEdmModel(),typeof(Customer)), request);
//act
var result = controller.Get(opts);
//assert
Assert.AreEqual(1, result.Items.First().CustomerID);
//排列
var request=newhttprequestmessage(HttpMethod.Get)http://localhost/MyProject/api/Customers?$filter=客户ID等式1“;
var控制器=新CustomerController
{
请求=请求
};
ODataModelBuilder modelBuilder=新ODataConventionModelBuilder();
modelBuilder.EntitySet(“客户”);
var opts=新的ODataQueryOptions(新的ODataQueryContext(modelBuilder.GetEdmModel(),typeof(Customer)),请求);
//表演
var结果=controller.Get(opts);
//断言
Assert.AreEqual(1,result.Items.First().CustomerID);
在最新的ODataController
中,有一个允许的查询选项
解决了这个问题
public class MyOdataController : ODataController
{
[Queryable(AllowedQueryOptions = AllowedQueryOptions.All)]
public IQueryable<Product> Get()
{
return Products.AsQueryable();
}
}
公共类MyOdataController:ODataController
{
[可查询(AllowedQueryOptions=AllowedQueryOptions.All)]
公共IQueryable Get()
{
退货产品。AsQueryable();
}
}
是否有一种方法可用于具有许多相关实体的EntitySet,这些实体都与您的测试逻辑无关?请参阅:为了单元测试,我需要通过Top并跳过。我该怎么做呢?这些字段是只读的。