首页 > 解决方案 > Linq 对对象的查询无法通过 Xunit 测试

问题描述

我有奇怪的问题。我必须通过以下 Xunit 测试:

Fact]
     public void GetOrder_ValidId_ReturnsCompleteOrder()
     {
         var service = new DataService();
         var order = service.GetOrder(10248);
         Assert.Equal(3, order.OrderDetails.Count);
         Assert.Equal("Queso Cabrales", order.OrderDetails.First().Product.Name);
         Assert.Equal("Dairy Products", order.OrderDetails.First().Product.Category.Name);
     }

我能够将 orderdetails 列表传递给测试。但是,我传递的“orderdetail”对象有一个带有 null 的产品对象。

我的课程是:

public class Order
{

    
    [Key] public int Id { get; set; }
    public DateTime Date { get; set; }

    public DateTime Required { get; set; }

   [Required] public virtual ICollection<OrderDetail> OrderDetails { get; set; }

    public string ShipName { get; set; }

    public string ShipCity { get; set; }
    
    public Order()
    {
        this.OrderDetails = new List<OrderDetail>();
    }
    
    public override string ToString()
    {
        string ret =
            $"Id = {Id}, DateTime = {Date}, Required = {Required}, shipName= {ShipName}, Shipcity = {ShipCity}";

        return ret;
    }
}

public class OrderDetail
{
    
    public Order Order { get; set; }
    
    [ForeignKey("orders")]
    public int Orderid { get; set; }
    
    [ForeignKey("products")]
    public int productid { get; set; }
    
    public int UnitPrice { get; set; }
    
    public int Quantity { get; set; }
    
    public int Discount { get; set; }
    

    [Required] public virtual Product Product { get; set; }
    public OrderDetail()
    {
        Product = Product;
    }
    
    public override string ToString()
    {
        return
            $"OrderId = {Orderid}, Productid = {productid}";
    }

}


public class Product
{
    [ForeignKey("orderdetails")] public int Id { get; set; }
    public string Name { get; set; }
    public float UnitPrice { get; set; }
    public string QuantityPerUnit { get; set; }
    public int UnitsInStock { get; set; }
    public int CategoryId { get; set; }
    public Category Category { get; set; }

     public virtual ICollection<OrderDetail> OrderDetails { get; set; }

    
    


    public override string ToString()
    {
        return
            $"Id = {Id}, Name = {Name}, UnitPrice = {UnitPrice}, QuantityPerUnit = {QuantityPerUnit}, UnitsInStock = {UnitsInStock}, CategoryId = {CategoryId}";
    }
}

我尝试了以下两种解决方案:

public Order GetOrder(int id)
    {
        using var ctx = new NorthWindContext();

        var query =  ctx.Orders.AsQueryable().Where(o => o.Id == 10248).FirstOrDefault();
        

        ctx.SaveChanges();
        
        //var query2 = ctx.Orders.Include("orderdetails").Where()

        return query;


    }

 var query2 = ctx.Orders.Where(o => o.Id == 10248)
            .Select(a => new Order
            {
                Id = a.Id,
                OrderDetails = a.OrderDetails
            }).FirstOrDefault();

我试图重新配置映射但没有这样做。如果我执行相同的查询并在 foreach 循环中使用 Console.Writeline,我可以得出结论,每个 orderdetail 都有一个“产品”......我不断收到错误消息:“对象未设置为对象的实例”传递时到 xUnit 测试。

标签: c#linqentity-framework-core

解决方案


伊万斯的回应完成了这项工作。

首先我删除了using System.Data.Entity;

然后我将订单类更改为以下内容:

public class Order 
{

    
    [Key] public int Id { get; set; }
    public DateTime Date { get; set; }

    public DateTime Required { get; set; }

   [Required] public virtual List<OrderDetail> OrderDetails { get; set; }

    public string ShipName { get; set; }

    public string ShipCity { get; set; }
    
    public Order()
    {
        this.OrderDetails = new List<OrderDetail>();
    }
    
    public override string ToString()
    {
        string ret =
            $"Id = {Id}, DateTime = {Date}, Required = {Required}, shipName= {ShipName}, Shipcity = {ShipCity}";

        return ret;
    }
}

然后我像 Ivans 一样使用了以下查询:

 var query3 = ctx.Orders
            .Include(o => o.OrderDetails)
            .ThenInclude(d => d.Product)
            .ThenInclude(d => d.Category)
            .AsSingleQuery()
            .FirstOrDefault(o => o.Id == 10248);

推荐阅读