随机数生成器导致单元测试失败

时间:2013-12-27 14:01:33

标签: c# asp.net-mvc unit-testing

我正在学习单元测试,我无法理解为什么当我调试并逐步执行下面的单元测试时,它会通过但是当我运行测试时它会失败。我的单元测试如下:

[TestMethod]
        public void NewGamesHaveDifferentTargetsTothePreviousGame()
        {
            /* NOTE : At this point we need to add a random number generator 
             * to provide the digits for the hidden digits.  Using a random number 
             * generator will help ensure that different games have different 
             * hidden digits.
             * */
            //Arrange
            var theGame = new GuessingGame();

            //Act
            List<int> firstDigits = new List<int>(theGame.Target);
            theGame.NewGame();
            List<int> secondDigits = new List<int>(theGame.Target);
            theGame.NewGame();
            List<int> thirdDigits = new List<int>(theGame.Target);

            //Assert
            /* NOTE : this CollectionAssert.AreNotEqual is true even if the two 
             * collections have the same elements as long as they are in a 
             * different order.  
             * */
            CollectionAssert.AreNotEqual(firstDigits, secondDigits);
            CollectionAssert.AreNotEqual(secondDigits, thirdDigits);
        }

我的课程如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Prigmore2013_01.Models
{
    public class GuessingGame
    {
        public GuessingGame()
        {
            this.Guesses = new List<Guess>();
            this.Target = new List<int>() { 1, 2, 3 };
        }
        public List<int> Target { get; set; }
        public List<Guess> Guesses { get; set; }
       ...
        public void NewGame()
        {
            this.Target.Clear();
            var count = 4;
            var random = new Random();
            for (var i = 1; i < count; i++)
            {
                var swap = random.Next(1, 9);

                if (!this.Target.Contains(swap))
                {
                    this.Target.Add(swap);
                }
            }
        }
        ...
}

当我调试时,我可以看到我的随机数生成器在我的测试中使用theGame.newGame()调用,从而在我的列表中创建随机数。但是,当我运行测试时,我没有通过测试,因为: CollectionAssert.AreNotEqual(secondDigits, thirdDigits);包含相同的元素。有些人能够向我解释为什么当我调试它时会通过测试,但是当我正常运行时,secondDigitthirdDigits包含相同的元素以及如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

问题很可能是它执行得如此之快以致Random构造函数多次使用相同的值对随机数生成器进行播种,从而为您提供相同的随机数序列。

更改代码,以便在构造函数中初始化随机数生成器,并在对NewGame()的所有调用中使用相同的实例。

例如:

public class GuessingGame
{
    private Random _random;

    public GuessingGame()
    {
        this.Guesses = new List<Guess>();
        this.Target = new List<int>() { 1, 2, 3 };
        this._random = new Random();
    }
    public List<int> Target { get; set; }
    public List<Guess> Guesses { get; set; }
   ...
    public void NewGame()
    {
        this.Target.Clear();
        var count = 4;
        for (var i = 1; i < count; i++)
        {
            var swap = _random.Next(1, 9);

            if (!this.Target.Contains(swap))
            {
                this.Target.Add(swap);
            }
        }
    }

答案 1 :(得分:3)

尝试将random变量移出方法,进入类级别。创建一个没有种子的Random的新实例,并且快速连续(当你没有单步执行代码时)可能会导致生成的值都相同。

public class GuessingGame
{
    Random random;

    public GuessingGame()
    {
        random = new Random();

        this.Guesses = new List<Guess>();
        this.Target = new List<int>() { 1, 2, 3 };
    }

    ...