我有一个带有控制器的项目WebAPI2,它引用了一些其他服务,我知道一切正常,因为我已经发布了webapi并且正在工作但是现在我想进行一些单元测试。 在我原来的解决方案中,我创建了一个新的测试项目,并创建了我的测试方法:
[TestMethod]
public void GetVerifyLogin_ShouldReturnUser() {
UserAccountController controller = new UserAccountController();
var result = controller.GetVerifyLogin("2171251", "2171251");
Assert.IsNotNull(result);
}
当我运行测试时,我收到以下错误:
结果消息:测试方法 StagesApiMsaTest.UserAccountControllerTest.GetVerifyLogin_ShouldReturnUser 抛出异常:System.InvalidOperationException:找不到 引用合同的默认端点元素 ServiceModel客户端中的“RapidFunctionsService.R_Service” 配置部分。这可能是因为没有配置文件 找到您的应用程序,或者因为没有端点元素匹配 这个合同可以在客户元素中找到。
我正在测试的方法有几行代码,但我会提取方法的摘录:
foreach (var siteItem in siteResult.ResultSet)
{
result.SiteNum = siteItem.SiteNum;
result.DevNum = siteItem.DevNum;
result.TrasmitterCode = siteItem.TransmitterCode;
}
RapidFunctionsService.R_ServiceClient service = new RapidFunctionsService.R_ServiceClient();
RapidFunctionsService.ZipCodeVerifyDealerResult xipResult = service.ZipCodeVerifyForXmit(result.TrasmitterCode);
result.ZipCodeVerify = xipResult.ZipCodeVerifyDealer;
result.ZipCode = xipResult.ZipCode;
任何人都有任何见解为什么我在测试中收到此错误?
答案 0 :(得分:1)
进行单元测试时,应该单独测试类。这是通过模拟类依赖性来实现的。为了模拟依赖关系,你应该将它们传递(注入)到类中,例如通过构造函数注入。此外,您的类应该依赖于抽象(即接口或抽象类)而不是实现。这使您的代码可测试:
public class UserAccountController : Controller
{
private readonly IRServiceClient rServiceClient;
// class does not have hidden dependencies
public UserAccountController (IRServiceClient rServiceClient)
{
this.rServiceClient = rServiceClient;
}
public ActionResult GetVerifyLogin()
{
//...
foreach (var siteItem in siteResult.ResultSet)
{
result.SiteNum = siteItem.SiteNum;
result.DevNum = siteItem.DevNum;
result.TrasmitterCode = siteItem.TransmitterCode;
}
// instead of creating dependency here, you are use injected dependency
var xipResult = rServiceClient.ZipCodeVerifyForXmit(result.TrasmitterCode);
result.ZipCodeVerify = xipResult.ZipCodeVerifyDealer;
result.ZipCode = xipResult.ZipCode;
//...
}
}
现在,您可以模拟服务依赖性并单独测试控制器。例如。与NSubstitute(还有很多其他模拟框架):
[TestMethod]
public void GetVerifyLogin_ShouldReturnUser()
{
var rServiceClient = Substitute.For<IRServiceClient>();
rServiceClient.ZipCodeVerifyForXmit("foo").Returns("bar"); // just an example
var controller = new UserAccountController(rServiceClient);
var result = controller.GetVerifyLogin("2171251", "2171251");
Assert.IsNotNull(result);
}
此示例显示如何传递伪依赖关系,该依赖关系配置为返回预定义输入的预定义结果。这使得您的控制器测试可重复。