使用 Moq、NUnit 和 Shouldly 进行单元测试






3.86/5 (5投票s)
使用 Moq、NUnit 和 Shouldly 对 .NET 应用程序进行单元测试
引言
如今,随着应用程序变得越来越复杂,开发人员在创建或编辑功能时检查所有场景变得非常困难。 因此,一个单独的单元测试项目是必不可少的,以确保满足所有期望的功能参数,并且不会遗漏任何内容。 为了实现这一点,有时会模拟数据并应用条件断言来验证功能需求。 本技巧将阐明如何在 .NET 应用程序中使用 Moq
、NUnit
和 Shouldly
实现单元测试。
背景
NUnit
已经存在很长时间了,但缺少一些关键的必要功能,例如数据模拟,其中使用 Moq
模拟来自某些外部功能的响应,以测试给定的功能,以及 Shouldly
使断言更易于理解和有意义。
Moq
和 Shouldly
都作为 nuget 包提供。
Using the Code
为了展示如何进行函数模拟,Moq
用于根据某些条件设置给定函数以返回预定义的响应。
Shouldly
提供现成的包装函数来断言可接受的条件。
[Test]
public void TestGetRailwayStationById()
{
var mockClassBll = new Mock<IBll>();
mockClassBll.Setup(c => c.GetRailwayStationById(It.IsAny<int>()))
.Returns(new RailwayStationDs(1, "New Delhi"));
var objRailwayStation = new RailwayStation(mockClassBll.Object);
var result = objRailwayStation.GetRailwayStationById(1);
result.ShouldNotBeNull();
result.StationName.ShouldNotBeEmpty();
}
[Test]
public void TestGetRailwayStationByString()
{
var mockClassBll = new Mock<IBll>();
mockClassBll.Setup(c => c.GetRailwayStationByName(It.IsAny<string>()))
.Returns(new RailwayStationDs(1, "New Delhi"));
var objRailwayStation = new RailwayStation(mockClassBll.Object);
var result = objRailwayStation.GetRailwayStationByName("New Delhi");
result.ShouldNotBeNull();
result.StationId.ShouldBeGreaterThan(0);
}
使用保存的输入参数和输出对复杂函数进行单元测试
在应用程序中,有一些非常复杂的函数,它们根据内部的许多情况返回不同的结果,并且很难检查所有这些情况。 因此,对这些函数进行单元测试的最佳方法是保存所有输入参数及其预期的输出。 此类测试数据可以保存到数据库或 XML 文件中,并在单元测试期间重复使用以验证所有情况。 当编辑此类复杂函数并且无意中更改一个或多个情况的功能并返回错误结果时,此类测试数据最适合这些情况。
[TestMethod]
[DataSource("System.Data.SqlClient",
@"Data Source=SAURABH\ADVANCE;Initial Catalog=TestDB;
Integrated Security=True", "dbo.StatusTestData",
DataAccessMethod.Sequential)]
public void TestStatusDataDrivenSQL()
{
TestContext.ShouldNotBeNull();
var strTime = TestContext.DataRow["Time"].ToString();
var varTime = TimeSpan.Parse(strTime);
var varStatus = TestContext.DataRow["Status"].ToString();
var objBll = new ClassBLL1();
var result = objBll.CurrentStatus(varTime);
result.ShouldNotBeNullOrEmpty();
result.ShouldBe(varStatus);
}
[TestMethod]
[DeploymentItem(".\\UnitTestBLL\\XMLTestCases.xml")]
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.XML",
@"XMLTestCases.xml", "case", DataAccessMethod.Sequential)]
public void TestStatusDataDrivenXML()
{
TestContext.ShouldNotBeNull();
var strTime = TestContext.DataRow["Time"].ToString();
var varTime = TimeSpan.Parse(strTime);
var varStatus = TestContext.DataRow["Status"].ToString();
var objBll = new ClassBLL1();
var result = objBll.CurrentStatus(varTime);
result.ShouldNotBeNullOrEmpty();
result.ShouldBe(varStatus);
}