我目前正在开发一个C#项目。我刚开始需要学习如何进行单元测试,并且发现它们很难绕过它的某些部分。我有一个返回List数组的函数,我需要测试此方法是否正常工作。
当我右键单击VS2010中的方法并说创建单元测试时,它会创建以下代码:
[TestMethod()]
public void readStreamTest()
{
ReadStream target = new ReadStream(); // TODO: Initialize to an appropriate value
Stream stream = new MemoryStream(); // TODO: Initialize to an appropriate value
StreamWriter sw = new StreamWriter(stream);
string line = "My Line 1\n¬My Line 2\nMy Line 3\nMy Line 4\nMy Line 5\nMy Line 6\nMy Line 7";
int numLines = 5; // TODO: Initialize to an appropriate value
List<FileLine> lines = new List<FileLine>();
int i = 0;
while ( i != 7 )
{
lines.Add(new FileLine()
{
lineNo = i,
lineContent = line
});
i++;
}
List<FileLine> expected = lines; // TODO: Initialize to an appropriate value
List<FileLine> actual;
actual = target.readStream(stream, numLines);
//Assert.AreEqual(expected, actual);
Assert.IsNotNull(expected);
}
其中一些,比如列表的初始化以及使用数组向列表添加项目是我自己添加的内容,试图找出要做的事情。
如果有人可以提供有关我如何测试它的任何帮助,我看不出它如何使用列表数组。
答案 0 :(得分:10)
让我们首先解决您的问题,然后我们可以讨论一般的测试指针。
Assert.AreEqual
将比较参考相等性,这不是您想要的。你真正想要的是比较内容是否相同(我假设)。这可以使用Enumerable.SequenceEqual
方法完成,如下所示:
Assert.IsTrue(expected.SequenceEqual(actual));
现在我们可以更广泛地谈论测试。我有posted about this before,但我会尝试总结这里的主题。
单元测试应该是关于行为,不是实现细节!这是我认为的第一个也是最基本的原则。它会告知你做出的每一个其他决定。
为什么这么重要?
因为如果你不这样做,那么你的测试就会变脆。 更改实施细节将破坏测试,这不应该发生。您的单元测试应该让您自由地重构和改进代码。如果您的测试与实现细节相关联,则不会发生这种情况,并且您将始终与测试作斗争。
那么这是什么样的?那么让我们比较两个假设的测试:
[TestMethod]
public void TestThatUserInfoIsValidatedAndSaved()
{
var user = new User{Name = "Bob"};
UserService.SaveUser(user);
//Check that data access got called to see if Bob exists
//Check that validation got called
//Check that data access got called to save bob
}
[TestMethod]
public void ShouldSaveNewUser()
{
var user = new User{Name = "Bob"};
UserService.SaveUser(user);
//Check that bob was saved
}
在前两种方法中,一种是非常精细地测试有关该方法的特定细节,而另一种只是测试预期的行为。如果我们改变该方法在引擎盖下工作的方式,那么第一个方法就会破坏。但是,第二次测试应该继续正常工作。
您的测试应该描述系统所做的“What”,而不是“how”它。
这样做,从长远来看,您将获得更好的单元测试经验。