junit NUnit:如何从一个非静态方法传递TestCaseData?

hk8txs48  于 2022-11-11  发布在  其他
关注(0)|答案(2)|浏览(138)

我的测试失败,因为出现以下消息:

The sourceName specified on a TestCaseSourceAttribute must refer to a static field, property or method.

这是我的代码:

const double MAX_DELTA = 0.01;
Qv_ges qv_ges_NE;
double Sum_Qv_ges_R_FL;
Qv_ges Qv_ges_Quer;

[SetUp]
public void init()
{
    qv_ges_NE = Din1946.Calc_Qv_ges_NE(205.7d);
    Sum_Qv_ges_R_FL = 15d + 15d + 15d + 15d + 15d + 10d + 10d + 10d + 10d + 10d + 10d + 10d;
    Qv_ges_Quer = Din1946.Calc_Qv_ges_Quer(qv_ges_NE, Sum_Qv_ges_R_FL);
}

public IEnumerable<TestCaseData> TestCases_A()
{
    yield return new TestCaseData(72.5, Qv_ges_Quer.FL.Value, MAX_DELTA);
    yield return new TestCaseData(169.17, Qv_ges_Quer.RL.Value, MAX_DELTA);
    yield return new TestCaseData(241.67, Qv_ges_Quer.NL.Value, MAX_DELTA);
    yield return new TestCaseData(314.17, Qv_ges_Quer.IL.Value, MAX_DELTA);
}

[TestCaseSource("TestCases_A")]
public void MethodA(double expected, double value, double latitude)
{
    Assert.AreEqual(expected, value, latitude);
}

我只使用了静态测试用例方法,但现在我需要访问非静态数据,如变量Qv_ges_QuerQv_ges_Quer.IL.ValueQv_ges_Quer.FL.Value....所以我删除了static

问题:

如何使用非静态测试用例?
我还注意到,通过调试,它不进入设置在第一。
这是我的旧代码,我想重新组织,也许你知道另一个/更好的方式,然后上面的方式:

public void MethodA()
{
    Qv_ges qv_ges_NE = Din1946.Calc_Qv_ges_NE(205.7d);

    double Sum_Qv_ges_R_FL = 15d + 15d + 15d + 15d + 15d + 10d + 10d + 10d + 10d + 10d + 10d + 10d;
    Qv_ges Qv_ges_Quer = Din1946.Calc_Qv_ges_Quer(qv_ges_NE, Sum_Qv_ges_R_FL);

    Assert.AreEqual(72.5, Qv_ges_Quer.FL.Value, MAX_DELTA);
    Assert.AreEqual(169.17, Qv_ges_Quer.RL.Value, MAX_DELTA);
    Assert.AreEqual(241.67, Qv_ges_Quer.NL.Value, MAX_DELTA);
    Assert.AreEqual(314.17, Qv_ges_Quer.IL.Value, MAX_DELTA);
}
ewm0tg9j

ewm0tg9j1#

🧟‍♀️ * 僵尸React,但迟总比没有好。*🧟
另一种实现方法是让测试用例数据源返回一个函数对象,该对象接受所需的非静态成员作为其参数,然后测试调用该对象来创建希望NUnit传递给您的数据。
在您的情况下,它看起来像这样:

private static IEnumerable<TestCaseData> GetTestDataA()
{
    yield return new TestCaseData(72.5,   new Func<Qv_ges, double>( qvGesQuer => qvGesQuer.FL.Value ), MAX_DELTA);
    yield return new TestCaseData(169.17, new Func<Qv_ges, double>( qvGesQuer => qvGesQuer.RL.Value ), MAX_DELTA);
    yield return new TestCaseData(241.67, new Func<Qv_ges, double>( qvGesQuer => qvGesQuer.NL.Value ), MAX_DELTA);
    yield return new TestCaseData(314.17, new Func<Qv_ges, double>( qvGesQuer => qvGesQuer.IL.Value ), MAX_DELTA);
}

[TestCaseSource( nameof(GetTestDataA) )]
public void MethodA( double expected, Func<Qv_ges, double> getValue, double latitude)
{ 
    Assert.AreEqual( expected, getValue( Qv_ges_Quer ), latitude );
}

如果你需要多个参数,把它们添加到函子和lambda的参数中,或者考虑传入this。如果你需要多个返回值,让函数对象返回一个元组:

new Func<Qv_ges, (double, double)>( qvGesQuer => (qvGesQuer.RL.Value, qvGesQuer.IL.Value) )

另一种方法是传入nameof()字符串作为测试参数,并使用反射来获取这些参数的值。

t40tm48m

t40tm48m2#

根据设计,TestCaseSourceAttribute使用的方法、属性或字段必须是静态的。这是为了避免在加载测试时示例化fixture类的需要。您的fixture只在我们开始运行时示例化-在GUI的情况下,每次我们开始运行时-并且它的生存期只与运行fixture所需的时间一样长。
在你的例子中,你似乎已经发现你可以使用一个静态方法。如果可能的话,这是最好的。
在这里使用示例方法的唯一方法是使用构造函数TestCaseSourceAttribute(Type sourceType)其中sourceType实现IEnumerable并直接返回您的测试用例数据。如果您使用这个,我建议您使用TestFixture中的不同类。这不是绝对必要的。如果您使用相同的类,在加载时和运行时将创建不同的示例,这两种状态之间没有任何联系。许多开发人员最终会对此感到困惑,并试图在加载时留下状态以供测试使用。这是行不通的。

相关问题