C# 方法引用服务出现WebAPI 2单元测试错误

C# 方法引用服务出现WebAPI 2单元测试错误,c#,unit-testing,asp.net-web-api,C#,Unit Testing,Asp.net Web Api,我有一个webapi 2项目,其中的控制器引用了一些其他服务,我知道一切都很好,因为我已经发布了webapi并开始工作,但现在我想做一些单元测试。在我的原始解决方案中,我创建了一个新的测试项目,并创建了我的测试方法: 当我运行测试时,出现以下错误: 结果消息:测试方法 StagesApiMsaTest.UserAccountControllerTest.GetVerifyLogin\u应返回用户 引发异常:System.InvalidOperationException:找不到 引用约定的默认端

我有一个webapi 2项目,其中的控制器引用了一些其他服务,我知道一切都很好,因为我已经发布了webapi并开始工作,但现在我想做一些单元测试。在我的原始解决方案中,我创建了一个新的测试项目,并创建了我的测试方法:

当我运行测试时,出现以下错误:

结果消息:测试方法 StagesApiMsaTest.UserAccountControllerTest.GetVerifyLogin\u应返回用户 引发异常:System.InvalidOperationException:找不到 引用约定的默认端点元素 ServiceModel客户端中的“RapidFunctionsService.R_服务” 配置部分。这可能是因为没有配置文件 为应用程序找到,或者因为没有匹配的端点元素 可以在client元素中找到此合同

我正在测试的方法有几行代码,但我将对该方法进行摘录:

 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;

有人知道我为什么在测试中出现这个错误吗?

在进行单元测试时,应该单独测试类。这是通过模拟类依赖关系实现的。为了模拟依赖项,应该将它们传递到类中,例如通过构造函数注入。此外,您的类应该依赖于抽象,即接口或抽象类,而不是实现。这使您的代码具有可测试性:

现在,您可以模拟服务依赖关系并单独测试控制器。例如,有很多其他模拟框架:

[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);
}
此示例显示如何传递假依赖项,该依赖项被配置为返回预定义输入的预定义结果。这使得控制器测试可重复


进一步阅读:

测试中的方法与实现问题紧密耦合,这些问题在实际运行环境之外似乎不起作用。封装这些依赖项,以便对它们进行模拟,从而允许对代码进行单独的单元测试。此外,还应调查错误消息的最后几行。您是否缺少测试项目中应该存在的配置信息。我不太确定测试项目中是否需要任何配置文件,因为测试项目位于同一解决方案下,并引用了默认的webapi项目。测试项目在其自己的上下文下执行,将需要其自己的配置文件好,我明白了,让我试试,所以我需要在我的测试项目上创建一个app.config,并引用我的服务?非常感谢你的解释,这对我非常有帮助,因为我是测试新手。Thanks@JoseRaulPerera:我强烈建议您阅读链接文章-遵循这些指导原则将在很大程度上改进您的单元测试,我肯定会这样做。
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;  

        //...          
    }
}
[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);
}