我将以下课程用作模拟课程:
public class MockData
{
public static MockData Current { get; } = new MockData();
public List<ClientViewModel> Choices { get; set; }
public MockData()
{
Choices = new List<ClientViewModel>
{
new ClientViewModel { Answers = new[] { false, false, false } },
new ClientViewModel { Answers = new[] { true, true, true } },
new ClientViewModel { Answers = new[] { true, true, false } },
new ClientViewModel { Answers = new[] { true, false, true } },
new ClientViewModel { Answers = new[] { true, false, false } }
};
}
}
现在,我正在尝试测试上述用户选择,以查看ClientViewModel
类的每个实例是否都给了我期望的字符串答案。为此,我使用了以下测试方法:
[Fact]
public void ClientRequest_UserChoicesPassed_ReturnsRightAnswer()
{
// Arrange
var clientViewModel = MockData.Current.Choices[0];
// Act
var jsonResult = _controller.ClientRequest(clientViewModel) as JsonResult;
// Assert
string expectedAnswer = "It is a book";
Assert.Equal(expectedAnswer, ((ResultDTO)jsonResult.Value).Result);
}
这非常有效,并且我的测试已按预期通过。但是,这种方法的问题在于,我也必须对其他条目重复此测试,正如您所注意到的,我在测试的var clientViewModel = MockData.Current.Choices[0];
部分中使用了Arrange
来测试第一个条目,即不想为此编写多个测试来重复自己。我已经知道xNunit中的[Theory]
和[InlineData]
概念,但是,看来我在上课时遇到了一些困难,请参见以下内容:
[Theory]
[InlineData(MockData.Current.Choices[0], "It is a book")]
[InlineData(MockData.Current.Choices[1], "It is a pen")]
public void ClientRequest_UserChoicesPassed_ReturnsRightAnswer(ClientViewModel clientViewModel, string expectedAnswer)
{
//...
}
但这给了我以下例外:
属性参数必须是属性参数类型的常量表达式,typeof表达式或数组创建表达式
所以请让我知道,有什么办法,我能做些什么来防止重复这种方法?
答案 0 :(得分:4)
要实现此目的,可以将MemberDataAttribute
与公共静态方法一起使用,该方法将返回要使用的测试用例。这是一个示例:
public static IEnumerable<object[]> GetUserChoiceTestData()
{
yield return new object[] { MockData.Current.Choices[0], "It is a book" };
yield return new object[] { MockData.Current.Choices[1], "It is a pen" };
}
然后,您将像下面这样将其应用于您的测试理论:
[Theory]
[MemberData(nameof(GetUserChoiceTestData))]
public void ClientRequest_UserChoicesPassed_ReturnsRightAnswer(ClientViewModel clientViewModel, string expectedAnswer)
{
//...
}
只要静态方法是您正在运行的测试类的成员,这将起作用。如果它是另一个非静态类的成员,则需要另外将该类型提供给MemberDataAttribute
。
[MemberData(nameof(SomeOtherClass.GetUserChoiceTestData), MemberType = typeof(SomeOtherClass))]