繁体   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