【发布时间】:2017-08-03 11:10:35
【问题描述】:
我有一个单元测试:
[Test]
[TestCaseSource(typeof(AllExampleEnumValues))]
public void GivenSth_WhenSth_ThenSth(ExampleEnum enumValue)
{
// Given
var givenState = BaseClassProperty; // property from fixture's base class
systemUnderTest.SetSomeState(givenState);
// When
var result = systemUnderTest.AnswerAQuestion(
"What's the answer to"
+ " the Ultimate Question of Life,"
+ " the Universe,"
+ " and Everything?");
// Then
Assert.That(result, Is.EqualTo(42));
}
其中AllExampleEnumValues如下:
public class AllGranularities : IEnumerable
{
public IEnumerator GetEnumerator()
{
return Enum
.GetValues(typeof(ExampleEnum))
.Cast<ExampleEnum>()
.Select(ee => new object[] { ee })
.GetEnumerator();
}
}
在我的基类中:
protected int BaseClassProperty
{
get
{
return //depending on enumValue
}
}
如何在运行时在BaseClassProperty 中获取enumValue 参数的当前值,而不将其更改为函数并将enumValue 作为参数传递?
我知道我可以以某种方式遍历堆栈帧并从那里读取它(不,实际上,我不能:How can I get the values of the parameters of a calling method?),但也许有更优雅的解决方案?
我需要这个来提高测试的可读性——enumValue 会隐式影响读取 BaseClassProperty 的结果这一事实不会降低可读性,因为在我的领域中,这种依赖性对每个人来说都是显而易见的。
我一直在研究TextContext 类,但在这种情况下它似乎没有任何用处。正如 cmets 中所提到的,该值存在于测试的名称中 - 但是在这里解析字符串中的值是不可接受的,因为有时我们使用多个参数和通用测试用例。
另一条线索导致使用IApplyToTest 属性。但是,这需要将此属性应用于每个测试。
最后,另一条线索导致使用ITestAction,从内部我可以访问ITest 接口,它提供TestMethod 实例。它具有Arguments 属性!不幸的是 - 它是私人的。
【问题讨论】:
-
你需要什么价值?将其作为字符串而不是实际值可以吗?
-
@ThomasLevesque 我知道它存在于测试名称中。但是,我们有时会使用多个参数,从这样的字符串中解析值会太复杂而且不是很安全。不过感谢您的建议!
-
我认为最好的办法是在 NUnit 存储库中请求该功能。实施起来可能不太复杂。
-
如果不说明如何用 NUnit 术语翻译 Given/When/Then 方法,我认为这是不可能回答的。您单独指出它们是您自己设计的方法。
-
@Charlie 不,它们完全不相关。由于它们引起了一些混乱,我已将它们从 sn-p 中删除。它们只是对当前 sn-p 内容的巧妙包装。
标签: c# unit-testing nunit