我是Mocking的新手,对单元测试有点熟悉,最后决定用一个严格的TDD方法开始一个新项目。但是我有一个服务类和方法,我需要回顾性地添加测试,因为它已经从原型中提升。
我不知道在这个特定的测试中从哪里开始,这是涉及的类和方法:
public class PageService : IPageService
{
private readonly ITestService testServiceClient;
public PageService(ITestService testServiceClient)
{
this.testServiceClient = testServiceClient;
}
public Page GetPage(Guid websiteId, string pageKey)
{
Page builtPage = null;
// WCF SERVICE CALL I DO NOT WANT EXECUTING WHEN RUNNING UNIT TEST
// BUT RATHER WANT A BLANK NEW INSTANCE OF "PAGE" CREATED USING MOQ??
var page = testServiceClient.GetPage(websiteId, pageKey);
if (page == null)
return null;
builtPage = new Page();
[code here to build builtPage if input params ok] ...
return builtPage;
}
}
我正在努力做的是写一个测试,希望我可以扩展GetPage(...)
测试的所有排列,但是对于第一个测试,只需测试一个有效的websiteId
和{{已传入1}},如果是,则返回有效的pageKey
实例,并将单词测试断言为true。
Page
是一个WCF服务客户端,之前它被包含在testServiceClient
语句中,但是我已经将它移出了它,希望能够通过依赖注入来实现它,因为我觉得这将是测试所需的第一步,从我的理解,我需要给它一个假/嘲笑? wcf客户端而不是using()
返回已知的内存数据集?希望我在那里走上正轨。
所以这是我单元测试的初始蓝图(我正在使用Moq框架,testServiceClient.GetPage()
是Setup()
的新版本,如果您还没有使用Moq的最新版本):
Expect()
我不知道从哪里开始,或者我是否在正确的轨道上?我可以确认上面没有语法错误,我确实收到了一个例外:
/// <summary>
/// Tests service returns a valid instance of type `Page` when a valid website and valid page key is tested.
/// </summary>
[TestMethod]
public void Test_Valid_Website_And_Valid_PageKey_Returns_Valid_Instance_Of_Page()
{
// Arrange
Page page = null;
// Act
var newPage = new Page() { Title = "Mocked Version!?"};
testServiceClient = new Mock<ITestService>();
testServiceClient.Setup(x => x.GetPage(websiteId, "about-us")).Returns(newPage);
service = new PageService(testServiceClient.Object);
page = service.GetPage(websiteId, "about-us");
// Assert
Assert.IsInstanceOfType(page, typeof(Page), "Object was not of expected instance type.");
}
我所知道的是,我希望我的System.ArgumentException: Invalid setup on a non-overridable member:
x => x.GetPage(websiteId, "about-us").
返回一个新实例,因为service.GetPage(...)
和websiteId
有效,但我不希望它使用真实pageKey
1}} WCF调用...希望我理解正确模拟的想法。当你在该服务上使用testServiceClient.GetPage()
时,我是否通过Moq正确地告诉了它,实际上只返回一个新的页面实例?
非常感谢任何澄清!谢谢你们!
答案 0 :(得分:4)
我会说你走在正确的轨道上。如果ITestService确实是一个接口(如其名称所示),您将能够模拟它。
但是,当您定义安装程序时,Moq必须能够识别您的方法,并且看起来好像您以某种方式指示了接口上不存在的方法。
您没有向我们展示ITestService接口,也不知道websiteId
变量的类型。
如果你仔细看看Setup方法,你会发现它确实是一个通用方法,所以当你调用它时没有通用参数就会进行类型推断。
我的猜测是websiteId
的声明在某种程度上与GetPage的声明冲突。例如,如果websiteId
被声明为object
,则Moq将使用此签名来管理方法:
Page GetPage(object x, string y);
与
不一样Page GetPage(Guid x, string y);
无论如何,一旦你设法让安装程序工作,你对单元测试的基本想法似乎很好。您可以做的不仅仅是声明实例不为null,因为Mock将确保返回的实例与您原来设置的实例相同:
[TestMethod]
public void Test_Valid_Website_And_Valid_PageKey_Returns_Valid_Instance_Of_Page()
{
// Arrange
Page page = null;
// Act
var newPage = new Page() { Title = "Mocked Version!?"};
testServiceClient = new Mock<ITestService>();
testServiceClient.Setup(x => x.GetPage(websiteId, "about-us")).Returns(newPage);
service = new PageService(testServiceClient.Object);
page = service.GetPage(websiteId, "about-us");
// Assert
Assert.AreEqual(newPage, page);
}
注意更有价值的断言。