C# Xunit 测试每个值必须包含 4 个的列表

C# Xunit testing a list that must contain 4 of each value

所以我正在练习单元测试 (Xunit) 和 C#。我正在制作一个扑克游戏控制台应用程序。我有一个卡片组,里面有 52 张卡片。该列表由 Card class 组成,每张牌都有一个 int 值表示它是什么牌,例如值 1 是 A,值 13 是 King。 我如何进行单元测试来检查 52 张卡片的列表是否每个值都有 4 张?我只是为了练习而做的,想不出不太复杂的单元测试。

这是卡片class很简单:

public class Card
{
    public enum Suit
    {
        HEART = 1,
        SPADE,
        CLUB,
        DIAMOND
    }

    public int value { get; set; }
    public int suit { get; set; }
    public char letter { get; set; }
}

CreateDeck() 方法创建并returns 卡片组:

public class CardDeck
{
    public static List<Card> CreateDeck()
    {
        List<Card> cardDeck = new List<Card>();
        int maxCards = 52;

        int currentCardValue = 1;
        int currentSuitValue = 1;
        
        for (int i = 0; i < maxCards; i++)
        {
            cardDeck.Add(new Card { value = currentCardValue, suit = currentSuitValue, letter = Card.ReturnLetter(currentCardValue) });
            currentSuitValue++;
            if (currentSuitValue > 4) { currentSuitValue = 1; }
            //After 4 cards of the same value we raise the cards value
            if(i + 1 % 4 == 0)
            {
                currentCardValue++;
            }
        }
        return cardDeck;
    }
}

所以我想做一个Xunit测试:

 [Fact]
        public void CardDeck_ShouldHave4CardsOfEachValue()
        {
            List<Card> cardDeck = CardDeck.CreateDeck();

            ??????

        }

您的断言可以按值对卡片进行分组。然后你总共有 13 个组(每组花色不同的 13 张牌)。或者,您可以按花色分组,这意味着 4 个组有 13 个成员……尽管这并不能证明它们是独一无二的)。

对于前者,

Assert(cardDeck.GroupBy(x => x.value).Count() == 13).

当然将该断言更改为您正在使用的测试包的断言语言(不确定 XUnit),例如如果使用 Fluent Assertions,那就是

cardDeck.GroupBy(x => x.value).Should().HaveCount(13)

还有一些注意事项:

  • 您当前的算法不正确。它会使这个断言失败。我把它留给你。
  • 例如,这并不能证明 suit 的值是正确的,尤其是因为尽管将其声明为枚举,但您仍在使用 int for suit

于是从LINQ库中查了一些方法,找到了解决办法:

        [Fact]
        public void CardDeck_ShouldHave4CardsOfEachValue()
        {
            List<Card> cardDeck = CardDeck.CreateDeck();

            for(int i = 1; i <= cardDeck.Count / 4; i++)
            {
                var cardsWithIteratedValue = cardDeck.Where(x => x.value == i);
                Assert.True(cardsWithIteratedValue.Count() == 4);
            }

        }