【发布时间】:2012-02-22 18:43:28
【问题描述】:
假设我有一个类似于下面的单元测试,有没有办法编写一个单元测试而不是多个单元测试,但也可以避免在单元测试中使用 for 循环?
[Test]
public void RunTestWithMultipleOptions()
{
MyClass code = new MyClass();
code.Prefix = "{DS1}"; //Options are {DS1}, {DS2}, {DS3}, {DS4}
//Property could be set to
//code.Prefix = "{DS1}{DS2}";
//code.Prefix = "{DS1}{DS2}{DS3}";
//And so on
//Based on how many {DS} used a method needs calling
code.InputDataStore(1,"Data1");
//If used {DS1}{DS2} in Prefix then
//code.InputDataStore(1,"Data1");
//code.InputDataStore(2,"Data2");
//If used {DS1}{DS2}{DS3} in Prefix then
//code.InputDataStore(1,"Data1");
//code.InputDataStore(2,"Data2");
//code.InputDataStore(3,"Data3");
string OutputData = String.Empty;
code.Output += delegate(int Id, string Data)
{
if (Id == (int)OutputsEnum.OutputModified)
OutputData = Data;
};
//Call the input method which will raise the Output event which we can assert against
code.Input("hi there");
//Assert that output has replace the prefix {DS} with the data in the datastorecontent list
Assert.AreEqual("Data1hi there", OutputData);
}
我可以将属性值传递给单元测试方法并使用测试用例,但基于属性是什么 MyMethod 需要调用 x 次。如果没有在测试中添加循环,我想不出没有将所有渗透作为单独的单元测试的方法。
更新:以下是课程的主要内容:
public event Action<int, string> Output;
public string Prefix { get; set; }
public string Postfix { get; set; }
private List<string> DataStoreContents = new List<string>() { "", "", "", "" };
public void Input(string Data)
{
if (Output != null)
{
if (!String.IsNullOrEmpty(Prefix))
{
Prefix = Prefix.Replace("{DS1}", DataStoreContents[0]);
Prefix = Prefix.Replace("{DS2}", DataStoreContents[1]);
Prefix = Prefix.Replace("{DS3}", DataStoreContents[2]);
Prefix = Prefix.Replace("{DS4}", DataStoreContents[3]);
}
if (!String.IsNullOrEmpty(Postfix))
{
Postfix = Postfix.Replace("{DS1}", DataStoreContents[0]);
Postfix = Postfix.Replace("{DS2}", DataStoreContents[1]);
Postfix = Postfix.Replace("{DS3}", DataStoreContents[2]);
Postfix = Postfix.Replace("{DS4}", DataStoreContents[3]);
}
Output((int)OutputsEnum.OutputBeforeModified, Data);
Output((int)OutputsEnum.OutputModified, Prefix + Data + Postfix);
Output((int)OutputsEnum.OutputAfterModified, Data);
}
}
}
public void InputDataStore(int DataStore, string Data)
{
if (DataStore < 1 || DataStore > 4)
throw new ArgumentOutOfRangeException("Datastore number out of range");
DataStoreContents[DataStore - 1] = Data;
}
}
我想测试一下,当我调用 InputDataStore(1,"MyData1"); InputDataStore(2, "MyData"); 时,Output 实际上确实将相关的 {DS1} 值替换为相关的字符串,并将其与任何其他 {DS} 值结合起来
【问题讨论】:
-
如果需要,为什么不能使用循环?
-
如果你在测试你的方法在多次执行时的行为(比如在for循环中),那么在我看来,循环是完全合适的。
-
为什么不在测试中放置 for 循环是不好的做法?就像“
被认为是有害的”的任何信念一样,事物的使用总是完全合理的,试图避免它只会创建不太可维护的代码。你想要一个循环,所以使用一个循环。 :-) -
你测试的方法好像很臭
-
@Jon:测试中的循环在偷工减料或重复测试代码逻辑方面很糟糕。当你需要使用循环时,把它当作早先出现问题的标志(但有时它是唯一的方法)。为什么你的
string属性表现得好像它是一个列表?它几乎是在问“让我成为一个列表/集合”。
标签: c# .net unit-testing nunit