如何使用C#中的代码进行单元测试

时间:2019-11-21 08:21:42

标签: c# unit-testing

因此,我正在做一个简单的扑克测试,其中我必须显示玩家的姓名和手牌,然后较高手的玩家获胜。对于该测试,没有纸牌花色和等级(例如,十张黑桃,钻石杰克),而是玩家应该拥有的牌手类型(例如,皇家同花顺,直牌,高牌等)。输出应如下所示:

Player 1, Jane's hand is: Full House
Player 2, John's hand is: One Pair
Winner: Jane (Full House)

现在,我已经完成了所有逻辑工作(您将在下面看到)。但是,我现在应该对此进行单元测试。我看过一些教程,但是如果您在下面看到我的代码,我认为它不适合单元测试。如果有人可以帮助我修复用于单元测试的代码,那么我将非常感激。

代码如下:

public class PokerGame
{
    static void Main(string[] args)
    {
        // Names of the players
        string player1Name, player2Name;

        // The array of the poker hands
        string[] pokerHands =
        {
            "High Card", "One Pair", "Two Pair", "Three of a Kind", "Straight", "Flush",
            "Full House", "Four of a Kind", "Straight Flush", "Royal Flush"
        };

        // This will prompt the players to type their name
        Console.Write("Enter Player 1: ");
        player1Name = Console.ReadLine();
        Console.Write("Enter Player 2: ");
        player2Name = Console.ReadLine();

        // This Random object will deal random hands accordingly
        Random randomHand = new Random();

        // The random hand index assigned to Player 1
        int hand1 = randomHand.Next(pokerHands.Length);

        // The random hand index assigned to Player 2
        int hand2 = randomHand.Next(pokerHands.Length);

        Console.WriteLine("Player 1, " + player1Name + "'s, hand is: " + pokerHands[hand1]);
        Console.WriteLine("Player 2, " + player2Name + "'s, hand is: " + pokerHands[hand2]);

        // If the random hand index for Player 1 is greater than that for Player 2
        if (hand1 > hand2)
        {
            // Then Player 1 wins
            Console.WriteLine("Winner: " + player1Name + " (" + pokerHands[hand1] + ").");
        }
        // But if it's the opposite
        else if (hand1 < hand2)
        {
            // Player 2 wins
            Console.WriteLine("Winner: " + player2Name + " (" + pokerHands[hand2] + ").");
        }
        // And if they have the same hands
        else
        {
            Console.WriteLine("It's a tie!");
        }

        Console.ReadLine();
    }
}

编辑:在获得一些朋友和Facebook(LOL)上的人的帮助之后,我设法将一些代码重构为:

public class PokerDealer
    {
        string[] hands =
            {
                "High Card", "One Pair", "Two Pair", "Three of a Kind", "Straight", "Flush",
                "Full House", "Four of a Kind", "Straight Flush", "Royal Flush"
            };

        public void DealCards(int hand1, int hand2, string name1, string name2)
        {
            Random randomHand = new Random();

            hand1 = randomHand.Next(hands.Length);
            hand2 = randomHand.Next(hands.Length);

            Console.WriteLine("Player 1, " + name1 + "'s hand: " + hands[hand1]);
            Console.WriteLine("Player 2, " + name2 + "'s hand: " + hands[hand2]);

            CheckWinner(hand1, hand2, name1, name2);
        }

        public int CheckWinner(int win1, int win2, string name1, string name2)
        {
            int winner;

            if (win1 > win2)
            {
                winner = win1;
                Console.WriteLine("Winner: " + name1 + " (" + hands[winner] + ")");
            }
            else if (win1 < win2)
            {
                winner = win2;
                Console.WriteLine("Winner: " + name2 + " (" + hands[winner] + ")");
            }
            else
            {
                winner = 0;
                Console.WriteLine("It's a tie!");
            }

            return winner;
        }
    }

DealCards()基本上是我的随机化器(提供随机卡),而CheckWinner()则检查谁拥有获胜卡。另外,我已经针对两个玩家的获胜条件进行了单元测试,并且它们都能正常工作!现在有一些问题:

  1. 我现在将如何测试他们是否拥有相同的卡? (最后一个条件)
  2. 我正在尝试对DealCards()进行测试,以查看玩家是否确实获得了随机纸牌,并查看纸牌是否未超出范围(0到9;可能更重要)。对于这一点,我不知道如何确定后一种情况。这是测试方法:
        [TestMethod]
        public void RandomHand()
        {
            // Tests if players are given a random hand within the range
            PokerDealer pd = new PokerDealer();
            Random randomHand = new Random();

            int randomHandIndex = randomHand.Next(10);
            pd.DealCards(randomHandIndex, randomHandIndex, "Player 1", "Player 2");
        }

1 个答案:

答案 0 :(得分:0)

为使代码更适合单元测试,我的建议是:仅 Main()方法应通过 Console.Write()打印文本。所有其他方法应仅返回值。这样,您的测试可以调用方法并检查关于返回值的假设。例如, CheckWinner()应该将其当前写入控制台的文本返回,以便您可以在测试中验证 CheckWinner()返回的字符串(也许重命名为< strong> GetResultText()之类的)与输入参数匹配。

对于测试某些场景,例如两个玩家拥有相同的手牌,有两种选择:

  • 为Random创建一个模型。这样,您可以控制在单元测试中使用时返回的值。这是一个高级主题,但这对于单元测试是非常有用的技术。 Google C#模拟。
  • 每次都为随机实例使用相同的种子(当然只有在测试时才使用!);这样,Next()调用返回的值将始终相同,您可以将其用于测试。例如

    Random r = new Random(9);
    Console.WriteLine(r.Next(10));
    Console.WriteLine(r.Next(10));
    

将连续两次为您提供-每一次。

关于最后一点,如何测试ranodm是否返回给定范围内的随机数。为什么要这么做?随机性不是代码的一部分,因此对其进行测试没有任何意义。