我正在为IHttpActionresult控制器编写测试方法。 ActionResult不是NULL并包含所需的数据(Customer.ID = 986574123)。但是在第二行中,变量CreatedResult为null。我希望它将适当的数据返回给CreatedResult。我也在使用Moq框架。不知道是否重要。有什么想法吗?如果您需要ActionResult的更多数据,请在下面发表评论。谢谢。
测试方法代码:
var CustomerRepository = new Mock<ICustomerRepository>();
CustomerRepository.Setup(x => x.Add()).Returns(new Customer { ID = 986574123, Date = DateTime.Now});
var Controller = new CustomerController(CustomerRepository.Object, new Mock<IProductRepository>().Object);
var config = new HttpConfiguration();
var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost:38306/api/CreateCustomer");
var route = config.Routes.MapHttpRoute("DefaultApi", "api/{controller}");
var routeData = new HttpRouteData(route, new HttpRouteValueDictionary { { "controller", "Customers" } });
Controller.ControllerContext = new HttpControllerContext(config, routeData, request);
Controller.Request = request;
Controller.Request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config;
IHttpActionResult ActionResult = Controller.CreateCustomer();
// Null occurs here
var CreatedResult = ActionResult as CreatedAtRouteNegotiatedContentResult<Customer>;
CreateCustomer添加方法:
[Route("api/createcustomer")]
[HttpPost]
public IHttpActionResult CreateCustomer()
{
Customer NewCustomer = CustomerRepository.Add();
return Created(Request.RequestUri + "/" + NewCustomer.ID.ToString(), new { customerID = NewCustomer.ID });
}
ActionResult数据:
- Location {http://localhost:38306/api/createcustomer/986574123} System.Uri
AbsolutePath "/api/createcustomer/986574123" string
AbsoluteUri "http://localhost:38306/api/createcustomer/986574123" string
Authority "localhost:38306" string
DnsSafeHost "localhost" string
Fragment "" string
Host "localhost" string
HostNameType Dns System.UriHostNameType
IsAbsoluteUri true bool
IsDefaultPort false bool
IsFile false bool
IsLoopback true bool
IsUnc false bool
LocalPath "/api/createCustomer/986574123" string
OriginalString "http://localhost:38306/api/createcustomer/986574123" string
PathAndQuery "/api/createCustomer/986574123" string
Port 38306 int
Query "" string
Scheme "http" string
+ Segments {string[4]} string[]
UserEscaped false bool
UserInfo "" string
答案 0 :(得分:0)
让测试通过的最简单的改变是改变这一行
return Created(Request.RequestUri + "/" + NewCustomer.ID.ToString(), new { customerID = NewCustomer.ID });
以下
return Created(Request.RequestUri + "/" + NewCustomer.ID.ToString(), NewCustomer);
问题是CreatedAtRouteNegotiatedContentResult的type参数不是您所期望的。您尝试将result
转换为CreatedAtRouteNegotiatedContentResult<Customer>
,而实际上其类型为CreatedAtRouteNegotiatedContentResult<AnonymousType#1>
,因此转换失败并返回null
。
原因是ApiController的Create(String, T)
方法返回一个CreatedAtRouteNegotiatedContentResult,其类型参数T
是您传入的content
的类型,而您&#39;重新传入anonymous type。
您希望使用匿名类型仅返回模型中的某些字段,但您还希望在声明它的上下文之外引用此类型(即在单元测试中)。这是不可能的,请参阅上面关于匿名类型(If you must store query results or pass them outside the method boundary, consider using an ordinary named struct or class instead of an anonymous type.
)
因此,如果您只想返回某些字段,则需要为此目的创建特定的视图模型。
class CustomerDetails
{
public int customerID { get; set; }
}
然后在你的行动方法中
return Created(Request.RequestUri + "/" + NewCustomer.ID.ToString(), new CustomerDetails { customerID = NewCustomer.ID });