Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing with multiple inputs

I've been trying to wrap my head around unit testing and I'm trying to deal with unit testing a function whose return value depends on a bunch of parameters. There's a lot of information however and it's a bit overwhelming..

Consider the following:

I have a class Article, which has a collection of prices. It has a method GetCurrentPrice which determines the current price based on a few rules:

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();
    }
}

The PriceType enum and Price class:

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; }
}

I want to create a unit test for the GetCurrentPrice method. Basically I want to test all combinations of rules that could possibly occur, so I would have to create multiple articles to contain various combinations of prices to get full coverage.

I'm thinking of a unit test such as this (pseudo):

[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
    } 
}
  • I've read that 'multiple asserts are evil', but don't I need them to test all conditions here? Or would I need a separate unit test per condition?

  • How would I go about providing the unit test with a set of test data? Should I mock a repository? And should that data also include the expected values?

like image 968
diggingforfire Avatar asked Aug 09 '26 11:08

diggingforfire


1 Answers

You are not using a repository in this example so there's no need to mock anything. What you could do is to create multiple unit tests for the different possible inputs:

[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
}

and so on you could add other unit tests where you would only change the arrange and assert phases for each possible input.

like image 132
Darin Dimitrov Avatar answered Aug 11 '26 00:08

Darin Dimitrov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!