2

我有以下单元测试:

[TestMethod]
public void NewGamesHaveDifferentSecretCodesTothePreviousGame()
{
    var theGame = new BullsAndCows();


    List<int> firstCode = new List<int>(theGame.SecretCode);
    theGame.NewGame();
    List<int> secondCode = new List<int>(theGame.SecretCode);
    theGame.NewGame();
    List<int> thirdCode = new List<int>(theGame.SecretCode);

    CollectionAssert.AreNotEqual(firstCode, secondCode);
    CollectionAssert.AreNotEqual(secondCode, thirdCode);
}

当我在调试模式下运行它时,我的代码通过了测试,但是当我正常运行测试(运行模式)时它没有通过。抛出的异常是:

CollectionAssert.AreNotEqual failed. (Both collection contain same elements).

这是我的代码:

// constructor
public BullsAndCows()
{
    Gueses = new List<Guess>();
    SecretCode = generateRequiredSecretCode();
    previousCodes = new Dictionary<int, List<int>>();
}

public void NewGame()
{
    var theCode = generateRequiredSecretCode();

    if (previousCodes.Count != 0)
    {
        if(!isPreviouslySeen(theCode))
        {
            SecretCode = theCode;
            previousCodes.Add(previousCodes.Last().Key + 1, SecretCode);  
        }
    }
    else
    {
        SecretCode = theCode;
        previousCodes.Add(0, theCode);
    }
 }

previousCodes是类的一个属性,它的数据类型是Dictionary 键整数,值 List of integersSecretCode也是类上的一个属性,它的数据类型是一个整数列表

如果我猜测一下,我会说原因是再次调用了 NewGame() 方法,而第一次调用还没有真正完成它需要做的事情。如您所见,在 NewGame() 方法中调用了其他方法(例如 generateRequiredSecretCode())。

在调试模式下运行时,我按 F10 的缓慢速度为进程提供了足够的时间结束。

但我不确定如何解决这个问题,假设我对原因的识别是正确的。

4

1 回答 1

0

generateRequiredSecretCode生成副本时,SecretCode 会发生什么?似乎没有处理。

一种可能性是您得到了一个副本,因此SecretCode保持与之前的值相同。发电机是如何工作的?

另外,你没有展示BullsAndCows构造函数是如何初始化的SecretCode?是叫NewGame吗?

我怀疑按键的速度与它有什么关系,因为您的测试方法会依次调用函数而无需等待输入。除非generateReq...产生一个线程,否则它将在返回之前完成它正在做的任何事情。

--更新后--

我看到 2 个错误。
1)SecretCode构造函数中生成的第一个不会添加到previousCodes. 因此,如果第二个游戏具有相同的代码,则不会进行重复检查。
2)previousCodes填充后,您不处理生成副本的情况。以前看到过重复项,因此您不会将其添加到previousCodes列表中,但您也不会更新SecretCode,因此它会保留旧值。

我不完全确定为什么这仅在发布模式下出现 - 但调试模式处理随机数生成器的方式可能有所不同。请参阅如何在 WPF 中随机化。发布模式更快,因此它使用与种子相同的时间戳,因此它实际上生成完全相同的数字序列。

If that's the case, you can fix it by making random a class property instead of creating a new one for each call to generator.

于 2013-01-17T19:21:25.687 回答