我有以下UnitTest:
[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键整数,值整数列表。 SecretCode 也是该类的属性,其数据类型是整数列表
如果我猜测,我会说原因是再次调用NewGame()方法,而第一个调用并没有真正完成它需要做的事情。如您所见,在NewGame()方法中调用了其他方法(例如generateRequiredSecretCode())。
在调试模式下运行时,按下F10的速度慢,可以为进程提供足够的时间。
但我不确定如何解决这个问题,假设我在确定原因时是正确的。
答案 0 :(得分:0)
当generateRequiredSecretCode
生成重复时,SecretCode会发生什么?它似乎未得到处理。
一种可能性是您获得了重复,因此SecretCode
保持与之前的值相同。发电机如何工作?
另外,您没有显示BullsAndCows
构造函数是如何初始化SecretCode
的?它在调用NewGame吗?
我怀疑按键的速度与它有什么关系,因为你的测试方法依次调用函数而不等待输入。除非generateReq...
产生一个线程,否则它将在它返回之前完成它正在做的任何事情。
- 更新后 -
我看到2个错误
1)构造函数中生成的第一个SecretCode
未添加到previousCodes
列表中。因此,如果第二个游戏具有相同的代码,则重复检查将无法捕获
2)填充previousCodes
后,您不会处理生成重复的情况。以前是重复的,因此您不会将其添加到previousCodes
列表中,但也不会更新SecretCode
,因此它会保留旧值。
我不确定为什么这只出现在发布模式中 - 但它可能与调试模式处理随机数生成器的方式不同。见How to randomize in WPF。释放模式更快,因此它使用与种子相同的时间戳,因此它确实生成完全相同的数字序列。
如果是这种情况,您可以通过使random
成为类属性来修复它,而不是为每次调用生成器创建一个新属性。