假设我有一个类似于下面的单元测试,有没有办法编写一个单元测试而不是几个,但也避免在单元测试中使用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次。如果没有在测试中使用循环,我就不会想到一种方法,如果没有将所有的permetations作为单独的单元测试。
UPDATE:以下是该课程的主要内容:
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}值相结合
答案 0 :(得分:2)
一种选择是将每个呼叫分开测试,并将它们全部放在一起。如果你测试A&amp; B&amp; C,你可以限制你自己测试A,B,C和A&amp; B&amp; C.一个选项是下一个代码(做出一些假设):
[TestFixture]
public class ToTestFixture
{
[SetUp]
public void SetUp()
{
_instance = new ToTest();
_instance.InputDataStore(1, "1");
_instance.InputDataStore(2, "2");
_instance.InputDataStore(3, "3");
_instance.InputDataStore(4, "4");
}
private ToTest _instance;
[TestCase("{DS1}","1")]
[TestCase("{DS2}", "2")]
[TestCase("{DS3}", "3")]
[TestCase("{DS4}", "4")]
[TestCase("{DS1}{DS2}{DS3}{DS4}", "1234")]
[Test]
public void TestPrefixReplacements(string input, string expectedResult)
{
_instance.Prefix = input;
//Call the input method which will raise the Output event which we can test
_instance.Input("Any string goes here as we test only prefix." );
Assert.AreEqual(expectedResult, _instance.Prefix);
}
}
internal enum OutputsEnum
{
OutputBeforeModified,
OutputModified,
OutputAfterModified
}
public class ToTest
{
public event Action<int, string> Output = (x, result) => Console.WriteLine(x.ToString() + result);
public string Prefix { get; set; }
public string Postfix { get; set; }
private List<string> DataStoreContents = new List<string>() {"1", "2", "3", "4"};
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;
}
}
无论如何我觉得“DS1”与数组索引之间存在联系。 (1-0,2-1)。这意味着下一次重构是可能的:
Prefix = Prefix.Replace("{DS"+index+"}", DataStoreContents[index-1]);
不仅如此,我猜输出动作决定很奇怪,两个if-s是重复代码。这就是我的意思:
public void Input(string Data)
{
if (Output != null)
{
Prefix = ApplyReplaceRules(Prefix);
Postfix = ApplyReplaceRules(Postfix);
Output((int) OutputsEnum.OutputBeforeModified, Data);
Output((int) OutputsEnum.OutputModified, Prefix + Data + Postfix);
Output((int) OutputsEnum.OutputAfterModified, Data);
}
}
private string ApplyReplaceRules(string patternString)
{
if (!String.IsNullOrEmpty(Postfix))
{
patternString = patternString.Replace("{DS1}", DataStoreContents[0]);
patternString = patternString.Replace("{DS2}", DataStoreContents[1]);
patternString = patternString.Replace("{DS3}", DataStoreContents[2]);
patternString = patternString.Replace("{DS4}", DataStoreContents[3]);
}
return patternString;
}