2

我正在编写一些 N 单元测试,但遇到了一些困难。我正在尝试将测试连接到TestCaseSource我的代码中的 a,但它似乎没有正确构造对象。

这是我的测试方法:

    [Test, TestCaseSource(typeof(TestCaseStuff), "GetTestCases", Category = "Release")]
    public void WithdrawMoney(TestCaseStuff tc)
    {
        double newBalance = AccountBalance - tc.amt;
        if (newBalance < 0)
        {
            Assert.Fail(String.Format("You can't withdraw {0}! You've maxed" +
                "out your bank account.", tc.amt.ToString("C2")));
        }

        AccountBalance = newBalance;
        Assert.Pass(String.Format("Your new balance is {0}.", 
        (AccountBalance).ToString("C2")));
    }

我的TestCaseSource

public class TestCaseStuff
{
    public double amt { get; set; }

    public TestCaseStuff()
    {
        Random rnd = new Random();
        this.amt = rnd.Next(0, 20);
    }

    [Category("Release")]
    public IEnumerable<TestCaseData> GetTestCases()
    {
        for (int i = 0; i < 500; i++)
        {
            yield return new TestCaseData(this);
        }
    }
}

这主要用作概念证明,因此当需要编写具有复杂对象的实际测试时,我会知道我可以像上面那样编写一个循环并将随机值放入我的对象中。但是,返回给我的测试方法的每个实例TestCaseStuff都是相同的。

更新:

下面的答案是正确的。当我将它传递给 N-UnitsTestCaseData对象时,我假设(错误地)它只会按值传递该实例。显然,它是通过引用完成的,这就是为什么值总是相同的。

最重要的是,我Random错误地使用了这个类。这不是我通常处理的事情,但我没有正确阅读它。正如下面链接中所解释的,当使用Random它的默认构造函数时,种子值是从系统时钟派生的。因此,如果您Random快速连续实例化多个对象,它们将共享相同的默认种子值并产生相同的值。

因此,由于这些发展,我的代码现在变为:

public class TestCaseStuff
{
    public double amt { get; set; }
    private static readonly Random rnd = new Random();

    public TestCaseStuff()
    {
        this.amt = rnd.Next(0, 20);
    }

    [Category("Release")]
    public IEnumerable<TestCaseData> GetTestCases()
    {
        for (int i = 0; i < 500; i++)
        {
            yield return new TestCaseData(new TestCaseStuff());
        }
    }

}
4

2 回答 2

3

上面的代码只会实例化一个副本TestCaseSource并继续提供相同的值。

如果打算在每个循环中生成一个随机数,我认为你应该制作一个对象的静态实例,并在每次创建新对象Random时从中生成一个数字。TestCaseStuff

我会像这样重写TestCaseStuff:

public class TestCaseStuff
{
    // Static instance of a random number generator.
    private static readonly Random RNG = new Random();

    public double amt { get; set; }

    public TestCaseStuff()
    {
        this.amt = RNG.Next(0, 20);
    }

    [Category("Release")]
    public IEnumerable<TestCaseData> GetTestCases()
    {
        for (int i = 0; i < 500; i++)
        {
            // NOTE: You need to create a new instance here.
            yield return new TestCaseData(new TestCaseStuff());
        }
    }
}
于 2012-10-10T15:03:13.220 回答
2

每次调用时,您都在创建一个新的 Random 实例:

yield return new TestCaseData(this);

尝试将其移出循环,您应该开始获得随机值。

发现这篇文章解释得很好! 如何播种随机类以避免获得重复的随机值

于 2012-10-10T14:49:25.673 回答