在dotnet环境中,我们通常使用NUnit和RhinoMocks来编写单元测试。
  NUnit 简介
  NUnit是.net平台上的一个单元测试框架,用来帮助开发人员方便的完成单元测试的编写。其主页为
  http://www.nunit.org,目前新版本为2.6.3.
  可以通过以下链接来查看不同版本的使用文档
  http://www.nunit.org/index.php?p=documentation
  Rhino Mocks简介
  Rhino Mocks是一个模拟对象创建和管理框架。使用它,开发人员可以方便地模拟并断言依赖对象被调用的情况。
  下载地址:http://hibernatingrhinos.com/downloads/rhino-mocks/latest
  如何编写测试用例
  创建一个测试工程,命名为{被测试工程}.UnitTest, 并添加NUnit和RhinoMocks引用。把项目属性中Application 面板中的Outputtype设置为Class Library
  对应的dll 分别nunit.framework.dll和Rhino.Mocks.dll
  创建测试类,命名为{被测试类}Test,测试类的目录结构和命名空间保持和被测试类一致。
  在测试类中引入命名空间NUnit.Framework和Rhino.Mocks
  using NUnit.Framework;
  using Rhino.Mocks;
  在测试类的summary注解中,列出测试列表,并把测试类使用[TestFixture]来标注
  [TestFixture]
  class SchoonerStorageTest
  {
  }
  针对测试列表来建立测试用例,并使用[Test]来标注,测试用例采用Test_{TestedMethod}_{测试点}_{预期结果}来命名,测试过程分三步走
  [Test]
  public void Test_{TestedMethod}_{测试点}_{预期结果}()
  {
  测试过程分三步:
  //准备测试数据
  //执行被测试方法
  //验证期望结果
  }
  单元测试中的NUnit
  测试用例执行过程
[TestFixture]
public class TestFixtureSetUpAndTearDownTest
{
[TestFixtureSetUp]
public void RunBeforeAllTests()
{
Console.WriteLine("TestFixtureSetUp");
}
[TestFixtureTearDown]
public void RunAfterAllTests()
{
Console.WriteLine("TestFixtureTearDown");
}
[SetUp]
public void RunBeforeEachTest()
{
Console.WriteLine("SetUp");
}
[TearDown]
public void RunAfterEachTest()
{
Console.WriteLine("TearDown");
}
[Test]
public void Test1()
{
Console.WriteLine("Test1");
}
}
  TestFixtureSetUp(这个测试类启动时被调用一次)
  SetUp(每个测试用例启动时被调用一次)
  Test(执行测试用例)
  TearDown(每个测试用例结束时被调用一次)
  TestFixtureTeardDown(这个测试类结束时被调用一次)
  断言使用(Assertions)
  有两种断言模型
  经典模型(classic model)
  相等断言(Assert.AreEqual, Assert.AreNotEqual...)
  引用相等断言(Assert.AreSame, Assert.AreNotSame...)
  比较断言(Assert.Greater, Assert.Less ...)
  类型断言(Assert.IsInstanceOfType, Assert.IsAssignableFrom...)
  条件断言 (Assert.True, Assert.False, Assert.IsNan, Assert.IsNull, Assert.IsEmpty)
  Assert类中有用的方法(这些方法运行你对测试进程进行控制)
  Assert.Pass:使测试用例成功
  The Assert.Pass method allows you to immediately end the test, recording it as successful. Since it causes an exception to be thrown, it is more efficient to simply allow the test to return. However, Assert.Pass allows you to record a message in the test result and may also make the test easier to read in some situations. Additionally, like the other methods on this page, it can be invoked from a nested method call with the result of immediately terminating test execution.
  Assert.Fail:使测试用例失败
  The Assert.Fail method provides you with the ability to generate a failure based on tests that are not encapsulated by the other methods. It is also useful in developing your own project-specific assertions.
  Assert.Ignore:忽略测试用例
  The Assert.Ignore method provides you with the ability to dynamically cause a test or suite to be ignored at runtime. It may be called in a test, setup or fixture setup method. We recommend that you use this only in isolated cases. The category facility is provided for more extensive inclusion or exclusion of tests or you may elect to simply divide tests run on different occasions into different assemblies.
  Assert.Inconclusive:测试用例使用现有测试数据不能正常完成(不是太理解这个方法的应用场景)
  The Assert.Inconclusive method indicates that the test could not be   completed with the data available. It should be used in situations where   another run with different data might run to completion, with either a   success or failure outcome.
  DirectoryAssert类
  FileAssert类
  CollectionAssert类
  StringAssert类
  基于约束的模型(constraint-based model)
  可以自定义约束来实现比较复杂的断言
  Assert.That(..)
  属性使用(Attributes)
  测试异常发生
  [Test(Description = "If the Id or Name attribute is not found in xpath 'StorageManagement/WritePolicy/CategoryConfig/CategoryList/Category', an exception will be thrown.")]
  [ExpectedException(ExpectedException = typeof(ConfigException), MatchType = MessageMatch.Contains, ExpectedMessage = "Id, Name attributes are required")]
  public void Test_LoadConfig_RequiredInfoNotFound_CategoryInWritePolicyCategoryList()
  {
  string confileFile = GetTestFile("CategoryStorageConfig_RequiredInfoNotFound_CategoryInWritePolicyCategoryList.xml");
  categoryStorageConfig.LoadConfig(confileFile);
  Assert.Fail("Failure");
  }