IHttpActionResult变量在测试方法中传递null

本文关键字:null 测试方法 变量 IHttpActionResult | 更新日期: 2023-09-27 18:09:36

我正在为IHttpActionresult控制器编写测试方法。ActionResult不是NULL,并且包含所需的数据(Customer。Id = 986574123)。但是在第二行中,变量CreatedResult为空。我希望它将适当的数据返回给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

IHttpActionResult变量在测试方法中传递null

使测试通过的最简单的更改将是更改这一行

return Created(Request.RequestUri + "/" + NewCustomer.ID.ToString(), new { customerID = NewCustomer.ID });

到下面的

return Created(Request.RequestUri + "/" + NewCustomer.ID.ToString(), NewCustomer);

问题是,你的createdatroutengoatedcontentresult的类型参数不是你所期望的。您尝试将result强制转换为CreatedAtRouteNegotiatedContentResult<Customer>,而实际上它的类型是CreatedAtRouteNegotiatedContentResult<AnonymousType#1>,因此强制转换失败并返回null

这样做的原因是ApiController的Create(String, T)方法返回一个createdatroutengotiatedcontentresult,其类型参数T是您传入的content的类型,并且您正在传入一个匿名类型。


你想使用匿名类型只从你的模型中返回某些字段,但是你也想在它被声明的上下文中引用这个类型(例如,在你的单元测试中)。这是不可能的,请参阅上面关于匿名类型(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 });