如何将数据模型与ASP.NET MVC 3中的儿童实体使用数据模型进行单位测试类



在我的网站应用程序中,我有一个"购物车"类,可以添加,删除和计算项目的总价值。数据模型是循环:1个项目包含1个产品和1个运输。产品具有价格字段,运输具有成本字段。这是购物车类代码:

public class CartLine
{
    public Item Item { get; set; }
    public int Quantity { get; set; }
}
public class Cart
{
    private List<CartLine> lineCollection = new List<CartLine>();
    // methods: 
    // Add(Item item, int quantity) 
    // Remove(Item item)
    public decimal ComputeTotalProductValue()
    {
        return lineCollection.Sum(l => l.Item.Product.Price*l.Quantity);
    }
    // methods with the same principle: 
    // ComputeTotalShippingValue()
    // ComputeOveralValue()
}

这是我的单位测试(当然不起作用):

[TestMethod]
    public void Can_Compute_Total_Values()
    {
        // Arrange 
        var itemMock = new Mock<IItemsRepository>();
        itemMock.Setup(i => i.GetItems()).Returns(new[]
            {
                new Item { ItemId = 1, ProductId = 1, ShippingId = 1 },
                new Item { ItemId = 2, ProductId = 2, ShippingId = 2 }
            });
        var productMock = new Mock<IProductRepository>();
        productMock.Setup(p => p.GetProducts()).Returns(new[]
            {
                new Product { ProductId = 1, Price = 10 },
                new Product { ProductId = 2, Price = 20 }
            });
        var shippingMock = new Mock<IShippingRepository>();
        shippingMock.Setup(s => s.GetShippings()).Returns(new[]
            {
                new Shipping { ShippingId = 1, Cost = 2 },
                new Shipping { ShippingId = 2, Cost = 5 }
            });
        var item1 = itemMock.Object.GetItems().ToArray()[0];
        var item2 = itemMock.Object.GetItems().ToArray()[1];    
        var target = new Cart();
        //Act
        target.Add(item1, 2);
        target.Add(item2, 4);
        decimal totalProduct = target.ComputeTotalProductValue();
        decimal totalShipping = target.ComputeTotalShippingValue();
        decimal overalSum = target.ComputeOveralValue();
        // Assert
        Assert.AreEqual(totalProduct, 100);
        Assert.AreEqual(totalShipping, 24);
        Assert.AreEqual(overalSum, 124);
    }
}

这个问题可能与将项目与产品和运输的绑定有关。我该怎么做?

预先感谢!

这里的根本问题是有关您如何坚持模型已泄漏到模型类的详细信息,因此,使用模型的类(例如CART使用项目)具有一些义务要了解您的持久性层,他们不需要做。这是太多的耦合,这就是使您的测试很难的原因。

考虑重新定义Item并添加ItemDescription So:

public class Item
{
   public Product Product {get;set;}
   public Shipping Shipping {get;set;}
}
public class ItemDescription
{
   public int ProductId {get;set;}
   public int ShippingId {get;set;}
}

这使您可以轻松地测试购物车和其他使用Item类的类。如果您需要的话,我可以添加一个例子,但是我猜这对您来说很明显。如果您由于某种原因无法更改Item,请颠倒将此接近倒入并为您的Cart创建FullyConsitituedItem类。

这里的成本是,您必须创建另一个从ItemDescription s创建Item s的类,但是实际上您会一直这样做,这只是在整个地方零碎完成。添加ItemDescription使其显式,更更好,更可读。

当然可以进行测试。

您需要在测试方法中直接为item1item2分配ProductShipping

请参阅代码示例:

[TestMethod]
public void Can_Compute_Total_Values()
{
    // Arrange 
    var item1 = new Item {
        Product = new Product { Price = 10 },
        Shipping = new Shipping { Cost = 2 }
    };
    var item2 = new Item {
        Product = new Product { Price = 20 },
        Shipping = new Shipping { Cost = 5 }
    };
    var target = new Cart();
    //Act
    target.Add(item1, 2);
    target.Add(item2, 4);
    decimal totalProduct = target.ComputeTotalProductValue();
    // Assert
    Assert.AreEqual(totalProduct, 100);
    Console.ReadLine();
}

在评论中提到的那样,无需模拟存储库,因为它们未在正在测试的方法中使用。这种方法宁可期望ProductShipping已经初始化。
因此,您需要准备正确的初始数据进行手动测试:)。

最新更新