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

C# 随机数生成器导致单元测试失败,c#,asp.net-mvc,unit-testing,C#,Asp.net Mvc,Unit Testing,我正在学习单元测试,我不明白为什么当我调试并逐步完成下面的单元测试时,它通过了,但当我运行测试时它失败了。我的单元测试如下: [TestMethod] public void NewGamesHaveDifferentTargetsTothePreviousGame() { /* NOTE : At this point we need to add a random number generator * to

我正在学习单元测试,我不明白为什么当我调试并逐步完成下面的单元测试时,它通过了,但当我运行测试时它失败了。我的单元测试如下:

[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);
                }
            }
        }
        ...
}
[TestMethod]
public void新游戏与前一个游戏有不同的目标()
{
/*注意:此时我们需要添加一个随机数生成器
*为隐藏数字提供数字。使用随机数
*生成器将有助于确保不同的游戏具有不同的
*隐藏的数字。
* */
//安排
var theGame=新猜游戏();
//表演
List firstDigits=新列表(theGame.Target);
theGame.NewGame();
List secondDigits=新列表(theGame.Target);
theGame.NewGame();
List thirdDigits=新列表(theGame.Target);
//断言
/*注意:此CollectionAssert.AreNotEqual为真,即使
*集合具有相同的元素,只要它们位于
*不同的顺序。
* */
CollectionAssert.AreNotEqual(第一位数字,第二位数字);
采集评估AreNotEqual(第二位数,第三位数);
}
我的班级如下:

[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);
                }
            }
        }
        ...
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web;
名称空间Prigmore2013_01.Models
{
公开课猜谜游戏
{
公众猜谜游戏
{
this.guesss=新列表();
this.Target=newlist(){1,2,3};
}
公共列表目标{get;set;}
公共列表猜测{get;set;}
...
公共游戏
{
this.Target.Clear();
var计数=4;
var random=新的random();
对于(变量i=1;i
调试时,我可以看到在测试中使用
theGame.newGame()
调用我的随机数生成器,从而在列表中创建随机数。但是,当我运行测试时,我测试失败,因为:
CollectionAssert.AreNotEqual(第二位数字,第三位数字)
;包含相同的元素。有些人能向我解释为什么调试时它通过了测试,但当我正常运行时,
第二位和第三位包含相同的元素,我如何解决这个问题?

最可能的问题是它执行得太快,以至于
随机
构造或者使用相同的值多次为随机数生成器种子,从而获得相同的随机数序列

更改代码,以便在构造函数中初始化随机数生成器,并在对
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);
            }
        }
    }
公共类猜谜游戏
{
私人随机(u Random),;
公众猜谜游戏
{
this.guesss=新列表();
this.Target=newlist(){1,2,3};
这个._random=new random();
}
公共列表目标{get;set;}
公共列表猜测{get;set;}
...
公共游戏
{
this.Target.Clear();
var计数=4;
对于(变量i=1;i
最可能的问题是,它执行得太快,以至于
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);
            }
        }
    }
公共类猜谜游戏
{
私人随机(u Random),;
公众猜谜游戏
{
this.guesss=新列表();
this.Target=newlist(){1,2,3};
这个._random=new random();
}
公共列表目标{get;set;}
公共列表猜测{get;set;}
...
公共游戏
{
this.Target.Clear();
var计数=4;
对于(变量i=1;i
尝试将
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 };
    }

    ...
公共类猜谜游戏
{
随机;
公众猜谜游戏
{
随机=新随机();
this.guesss=新列表();
this.Target=newlist(){1,2,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 };
    }

    ...
公共类猜谜游戏
{
随机;
公众猜谜游戏
{
随机=新随机();
this.guesss=新列表();
this.Target=newlist(){1,2,3};
}
...

要么使用模拟/伪随机数生成器,要么使用固定种子要么使用模拟/伪随机数生成器,要么使用固定种子谢谢你,这有用,不幸的是吉姆·米谢尔打败了你!谢谢你,这有用,不幸的是吉姆·米谢尔打败了你!