.net 具有WCF调用的单元测试服务(MSUnit&x2B;Moq)
我不熟悉Mocking,对单元测试有点熟悉,最后我决定用严格的TDD方法开始一个新项目。但是,我有一个服务类和方法需要回顾性地添加测试,因为它是从原型升级而来的 我不知道从哪里开始,但在这个特定的测试中,涉及的类和方法如下:.net 具有WCF调用的单元测试服务(MSUnit&x2B;Moq),.net,unit-testing,dependency-injection,mocking,moq,.net,Unit Testing,Dependency Injection,Mocking,Moq,我不熟悉Mocking,对单元测试有点熟悉,最后我决定用严格的TDD方法开始一个新项目。但是,我有一个服务类和方法需要回顾性地添加测试,因为它是从原型升级而来的 我不知道从哪里开始,但在这个特定的测试中,涉及的类和方法如下: public class PageService : IPageService { private readonly ITestService testServiceClient; public PageService(ITestService testS
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
和pageKey
,如果是,则接收一个有效的Page
实例,并断言单元测试为true
testServiceClient
是一个WCF服务客户机,以前它被包装在using()
语句中,但我已经将它移出了该语句,希望通过依赖项注入来实现它,因为我觉得这将是测试所需的第一步,据我所知,我需要给它一个假的/模拟的?wcf客户端,其中testServiceClient.GetPage()
返回内存中已知的数据集?希望我在那里走的是正确的道路
下面是我的单元测试的初始蓝图(我正在使用Moq框架,Setup()
是Expect()
的新版本,如果您没有使用最新版本的Moq):
我只知道我希望我的服务.GetPage(…)
返回一个新实例,因为websiteId
和pageKey
是有效的,但是我不希望它使用真正的testServiceClient.GetPage()
WCF调用。。。希望我能正确理解嘲弄的意思。当您在该服务上使用testServiceClient.GetPage
时,我是否通过Moq正确地告诉了您,实际上只是返回了一个新的page实例
任何澄清都将不胜感激!谢谢大家 我想说,你走在正确的轨道上。如果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);
}
[TestMethod]
public void Test_Valid_Website_和_Valid_PageKey_返回_Page()的_Valid_实例_
{
//安排
Page=null;
//表演
var newPage=newPage(){Title=“模拟版本!?”};
testServiceClient=new Mock();
testServiceClient.Setup(x=>x.GetPage(websiteId,“关于我们”)).Returns(newPage);
服务=新的页面服务(testServiceClient.Object);
page=service.GetPage(websiteId,“关于我们”);
//断言
Assert.AreEqual(新建页,第页);
}
请注意更有价值的断言。+1回答很好-@GONeale,为了证实Mark所说的,我使用MOQ和一个返回页面的界面运行了一个快速测试-它工作正常。看起来你是在模拟一个具体的实例,其中GetPage并没有声明为虚拟的。ITestService是一个WCF生成的服务客户机,(右键单击项目->添加服务引用)类型。鉴于此,我认为我不能将其声明为
virtual
,因为它是一个自动生成的类。但是,我可以创建一个简单的WCF调用方类,并将其虚拟化,这会有帮助吗?感谢Assert提示。声明testServiceClient.Setup(x=>x.GetPage(..)。Returns(newPage)
告诉任何对该方法名称的调用(嵌套,即使对象的方法作为参数传入,例如新页面服务(testServiceClient.object)
)要实际不运行实际(wcf)方法,而只返回一个newPage
实例?这就是为什么需要virtual
,它会用全新的方法内容覆盖它的原因吗?请原谅我对嘲弄的无知,我正在努力追赶,但是在我的工作场所,这是一个微妙的平衡,在让这个项目出门与允许研究的时间之间。典型的故事。w00t!!!我创建了一个WcfPageService
并声明了一个执行WCF往返的GetPage()
virtual方法,然后将其用作我的可模拟对象!工作得很有魅力!!谢谢各位,你们可以在这里查看适用的代码
Page GetPage(Guid x, string y);
[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);
}