我写了一个将人员列表写入文本文件的方法,在单元测试中,我想检查我是否为列表传递了 NULL,NullReferenceException 正在抛出。
方法
public void WriteToOutput(List<Person> list)
{
string outputFileName = "names-list.txt";
try
{
StreamWriter sw = new StreamWriter(outputFileName, false);
foreach (var item in list)
{
sw.WriteLine(item.givenNames + " " + item.lastName);
Console.WriteLine(item.givenNames + " " + item.lastName);//writting names to console
}
Console.WriteLine("Press Enter to Exit...");
sw.Close();
}
catch (NullReferenceException ex)
{
Console.WriteLine("List is Empty");
throw new NullReferenceException();
}
}
测试方法
[TestMethod]
public void WriteToOutput_NullableList_ThrowNullReferenceException()
{
//arrange
FileWriter fw = new FileWriter();
//act
Assert.ThrowsException<NullReferenceException>(()=> fw.WriteToOutput(null));
}
但我不想在 WriteToOutput 方法中抛出 NullReferenceException,而只想将消息写入控制台。 如果我从方法"写入输出"中删除"抛出新的 NullReferenceException",我的测试就会失败。
关于如何处理此问题的任何意见。
首先,您将删除对Console
的依赖并将其更改为Action<string>
。
public class FileWriter
{
public Action<string> Log { get; set; }
public void WriteToOutput(List<Person> list)
{
...
Log("List is Empty");
}
}
现在,您可以根据需要插入委托。
var writer = new FileWriter();
writer.Log = Console.WriteLine;
该类将写入控制台。
对于测试,我们提供不同的委托。
[TestMethod]
public void WriteToOutput_NullableList_ThrowNullReferenceException()
{
var message = "";
Action<string> testlog = (string msg) => { message = msg; };
var writer = new FileWriter();
writer.Log = testlog;
Assert.AreEqual(message, "List is Empty");
}
我会使用TextWriter进行输出
public class FileWriter
{
private readonly TextWriter _console;
public FileWriter(TextWriter console)
{
_console = console;
}
public void WriteToOutput(List<Person> list)
{
string outputFileName = "names-list.txt";
try
{
using (StreamWriter sw = new StreamWriter(outputFileName, false))
{
foreach (var item in list)
{
sw.WriteLine(item.GivenNames + " " + item.LastName);
_console.WriteLine(item.GivenNames + " " + item.LastName); //writting names to console
}
_console.WriteLine("Press Enter to Exit...");
sw.Close();
}
}
catch (NullReferenceException ex)
{
_console.WriteLine("List is Empty");
}
}
}
然后在测试中
var sb = new StringBuilder();
var fw = new FileWriter(new StringWriter(sb));
//act
fw.WriteToOutput(null);
Assert.AreEqual("List is Emptyrn", sb.ToString());
并在控制台的程序中
var peopleWriter = new FileWriter(Console.Out);
然后你也可以测试你的主案例
fw.WriteToOutput(new List<Person>()
{
new Person() { GivenNames = "Dula", LastName = "Hula" },
new Person() {GivenNames = "Ruby", LastName = "Nooby"}
});
Assert.AreEqual("Dula HularnRuby NoobyrnPress Enter to Exit...rn", sb.ToString());
由于您不想在人员列表为空时引发异常,因此您的测试应该与成功测试相反(当列表包含记录时)。这样,您就不依赖于控制台消息。或您可以更改方法WriteToOutput以返回布尔值,然后在测试中检查返回值,即
public void WriteToOutput(List<Person> list)
{
string outputFileName = "names-list.txt";
try
{
// other stuff
return true;
}
catch (NullReferenceException ex)
{
Console.WriteLine("List is Empty");
return false;
}
}
[TestMethod]
public void WriteToOutput_NullableList_ThrowNullReferenceException()
{
//arrange
FileWriter fw = new FileWriter();
//act
bool returnValue = fw.WriteToOutput(null);
//assert
Assert.IsFalse(returnValue);
}