假设我有一个类似于下面的单元测试,有没有一种方法可以编写一个单元测试而不是多个单元测试,同时又避免在单元测试中使用 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 次。如果不在测试中放置循环,我无法想出一种方法,而不将所有渗透作为单独的单元测试。
更新:以下是类(class)的主要内容:
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} 值组合起来
最佳答案
一种选择是单独测试每个调用,然后一起测试所有调用。如果您测试 A&B&C,您可以限制自己单独测试 A、B、C 以及一起测试 A&B&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;
}
关于c# - 在单元测试中进行多次调用而不使用 for 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9400979/