多输入单元测试

时间:2012-02-11 12:19:52

标签: c# unit-testing mocking

我一直在尝试围绕单元测试,我正在尝试处理单元测试一个函数,其返回值取决于一堆参数。然而,有很多信息,而且有点压倒性......

请考虑以下事项:

我有一个班级Article,它有一组价格。它有一个方法GetCurrentPrice,它根据一些规则确定当前价格:

public class Article
{
    public string Id { get; set; }
    public string Description { get; set; }
    public List<Price> Prices { get; set; }

    public Article()
    {
        Prices = new List<Price>();
    }

    public Price GetCurrentPrice()
    {
        if (Prices == null)
            return null;

        return (
            from
            price in Prices

            where

            price.Active &&
            DateTime.Now >= price.Start &&
            DateTime.Now <= price.End

            select price)
            .OrderByDescending(p => p.Type)
            .FirstOrDefault();
    }
}

PriceType枚举和Price类:

public enum PriceType
{
    Normal = 0,
    Action = 1
}

public class Price
{
    public string Id { get; set; }
    public string Description { get; set; }
    public decimal Amount { get; set; }
    public PriceType Type { get; set; }
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
    public bool Active { get; set; }
}

我想为GetCurrentPrice方法创建单元测试。基本上我想测试可能发生的所有规则组合,因此我必须创建多篇文章以包含各种价格组合以获得完全覆盖。

我正在考虑像(伪)这样的单元测试:

[TestMethod()]
public void GetCurrentPriceTest()
{
    var articles = getTestArticles();
    foreach (var article in articles)
    {
        var price = article.GetCurrentPrice();
        // somehow compare the gotten price to a predefined value
    } 
}
  • 我读过“多个断言是邪恶的”,但我不需要 他们在这里测试所有条件?或者我需要一个单独的单位 按条件测试?

  • 我如何使用一组测试数据提供单元测试? 我应该模拟存储库吗?并且该数据是否也包括 预期值?

4 个答案:

答案 0 :(得分:4)

您未在此示例中使用存储库,因此无需模拟任何内容。您可以做的是为不同的输入创建多个单元测试:

[TestMethod]
public void Foo()
{
    // arrange
    var article = new Article();
    // TODO: go ahead and populate the Prices collection with dummy data


    // act
    var actual = article.GetCurrentPrice();

    // assert
    // TODO: assert on the actual price returned by the method
    // depending on what you put in the arrange phase you know
}

等等,您可以添加其他单元测试,您只需更改每个可能输入的arrangeassert阶段。

答案 1 :(得分:2)

您不需要多个断言。您需要多次测试,每个测试只有一个断言。

答案 2 :(得分:2)

每个启动条件和单个断言的新测试,例如

[Test]
public void GetCurrentPrice_PricesCollection1_ShouldReturnNormalPrice(){...}

[Test]
public void GetCurrentPrice_PricesCollection2_ShouldReturnActionPrice(){...}

并测试边界

对于单元测试我使用模式

MethodName_UsedData_ExpectedResult()

答案 3 :(得分:2)

我认为您需要进行数据驱动测试。在vsts中有一个名为Datasource的属性,使用它可以发送一个测试方法多个测试用例。确保不要使用多个断言。这是一个MSDN链接http://msdn.microsoft.com/en-us/library/ms182527.aspx

希望这会对你有所帮助。