C# N单元中的TestCaseSource

C# N单元中的TestCaseSource,c#,.net,unit-testing,nunit,testcasesource,C#,.net,Unit Testing,Nunit,Testcasesource,我正在写一些N单元测试,有点困难。我试图将测试连接到代码中的TestCaseSource,但它似乎没有正确构造对象 以下是我的测试方法: [Test, TestCaseSource(typeof(TestCaseStuff), "GetTestCases", Category = "Release")] public void WithdrawMoney(TestCaseStuff tc) { double newBalance = AccountBala

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

以下是我的测试方法:

    [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")));
    }
主要是作为概念的证明,所以当需要编写一个复杂对象的实际测试时,我知道我可以编写一个类似上面的循环,并将随机值放入我的对象中。然而,返回到我的测试方法的
TestCaseStuff
的每个实例都是相同的

更新:

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

除此之外,我还错误地使用了
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());
        }
    }

}
公共类TestCaseStuff
{
公共双金额{get;set;}
私有静态只读随机rnd=new Random();
公共测试用例
{
本金额=下一个(0,20)日的净日数;
}
[类别(“发布”)]
公共IEnumerable GetTestCases()
{
对于(int i=0;i<500;i++)
{
返回新的TestCaseData(newtestcasestuff());
}
}
}

每次调用时都会创建一个新的随机实例:

yield return new TestCaseData(this);
尝试将其移动到循环之外,您应该开始获得随机值

发现这篇文章解释得很好!

上述代码将只实例化一个
TestCaseSource
副本,并继续提供相同的值

如果目的是在每个循环中生成一个随机数,我认为应该创建
随机
对象的静态实例,并在每次创建新的
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());
        }
    }
}
公共类TestCaseStuff
{
//随机数生成器的静态实例。
私有静态只读随机RNG=new Random();
公共双金额{get;set;}
公共测试用例
{
本金额=下一个(0,20)RNG;
}
[类别(“发布”)]
公共IEnumerable GetTestCases()
{
对于(int i=0;i<500;i++)
{
//注意:您需要在此处创建一个新实例。
返回新的TestCaseData(newtestcasestuff());
}
}
}

是的,我最后就是这么做的。当我传入
this
时,我以为TestCaseData会有自己的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());
        }
    }
}