簡體   English   中英

如何排除另一個邏輯並提高單元測試的性能

[英]How to exclude another logic and improve performance of unit tests

我正在嘗試提高項目中單元測試的性能。 如果我在一個邏輯中編寫測試,我需要在我的測試中編寫另一個邏輯。 我像這樣重現它:我有類 ProductInfo

    public class ProductInfo
{
    public string Name { get; set; }
    public string Title { get; set; }
}

和類產品:

 public class Product
{
    public ProductInfo Info { get; set; }

    private decimal price;
    public decimal Price
    {
        get
        {
            return price;
        }
        set
        {
            price = value;
            Info.Title = $"{Info.Name}-{price} USD";
        }
    }
}

我創建了用於設置價格的單元測試

[TestMethod]
    public void ProductInfoTitleTest()
    {
        decimal price = 120;
        string productName = "Product1";
        ProductInfo info = new ProductInfo() { Name = productName };
        Product product = new Product() { Info = info };
        product.Price = price;
        Assert.AreEqual($"{productName}-{price} USD", product.Info.Title, "Both should be equal");
    }

創建測試通過。 所以,我在 Product 類中創建了另一個屬性:

public int Quantity { get; set; }

    public decimal TotalPrice
    {
        get
        {
            return Price * Quantity;
        }
    }

然后我創建測試來測試 TotalPrice:

    [TestMethod]
    public void ProductTotalPriceTest()
    {
        Product product = new Product
        {
            Price = 100,
            Quantity = 2
        };
        Assert.AreEqual(200, product.TotalPrice, "It should be 200");
    }

這個測試失敗了,因為我沒有設置產品信息。 所以,我這樣做:

 [TestMethod]
    public void ProductTotalPriceTest()
    {
        Product product = new Product
        {
            Info = new ProductInfo(),
            Price = 100,
            Quantity = 2
        };
        Assert.AreEqual(200, product.TotalPrice, "It should be 200");
    }

然后測試通過。 有沒有辦法在不設置產品信息(不改變邏輯)的情況下做到這一點? 我希望我能理解用例。

如何排除另一個邏輯

你不應該 ProductInfo有效實例是Product類“合同”的一部分。

我什至建議構造構造函數的ProductInfo參數,以明確顯示類的使用者,如果沒有它,類將無法正常工作。

如果測試下的類的配置變得復雜,請創建幫助器/構建器類/函數,其中配置邏輯將保留在同一位置。

例如:

public class ProductBuilder
{
    private string _productName;
    private decimal _price;
    private int _quantity;

    public ProductBuilder ProductName(string name)
    {
        _productName = name;
        return this;
    }

    public ProductBuilder Price(decimal price)
    {
        _price = price;
        return this;
    }

    public ProductBuilder Quantity(int quantity)
    {
        _quantity = quantity;
        return this;
    }

    public Product Create()
    {
        return new Product
        {
            Info = new ProductInfo { Name = _productName },
            Price = _price,
            Quantity = _price, 
        }
    }
}

然后在測試中,您將能夠創建Product類型的有效實例。

[TestMethod]
public void InfoTitel_ReturnsProductNameAndPrice()
{
    var builder = new ProductBuilder();

    var product = builder.ProductName("Device X").Price(100).Create();

    product.Info.Title.Should().Be("Device X-100.00 USD");
}

[TestMethod]
public void TotalPrice_CalculatesFromPriceAndQuantity()
{
    var builder = new ProductBuilder();

    var product = builder.Price(35.99m).Quantity(2).Create();

    product.TotalPrice.Should().Be(71.98m);
}

通過將配置封裝到專用類中,您將能夠在不涉及每個測試的情況下更改配置邏輯。 除非,當然你會改變班級的公共合同。

這看起來是一個很好的機會,可以在每次測試之前使用測試初始化​​程序通過ProductInfo實例化Product ,然后根據需要修改它。

[TestClass]
public class ProductTests
{
    Product product;

    [TestInitialize]
    public void Setup()
    {
        product = new Product { Info = new ProductInfo() };
    }

    [TestMethod]
    public void ProductInfoTitleTest()
    {
        decimal price = 120;
        string productName = "Product1";
        product.Info.Name = productName;
        product.Price = price;
        Assert.AreEqual($"{productName}-{price} USD", product.Info.Title, "Both should be equal");
    }

    [TestMethod]
    public void ProductTotalPriceTest()
    {
        product.Price = 100;
        product.Quantity = 2;
        Assert.AreEqual(200, product.TotalPrice, "It should be 200");
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM