【问题标题】:Getting an error attemping to use .NET Core dependency injection with NUnit test classes尝试将 .NET Core 依赖注入与 NUnit 测试类一起使用时出现错误
【发布时间】:2016-10-12 23:10:40
【问题描述】:

单元测试和 .NET Core (1.0.1) 的新手,寻求帮助。

我希望对一些使用 .NET Core 依赖注入模式的类进行单元测试。应用程序运行良好,但在尝试使用需要 DI 的类运行 NUnit 测试时,错误输出:

处于状态时没有消息“TestExecution.TestResult”的处理程序 'TestExecutionSentTestRunnerProcessStartInfo' 发生异常 调用执行程序“executor://dotnetunittestexecutor/v1”时:无法 将数据写入传输连接:现有连接是 被远程主机强行关闭。现有的连接是 被远程主机强行关闭

在搜索该错误或任何有关将 DI 与 NUnit 结合使用的文档方面没有太多运气。我有一种感觉,我不应该像这样配置。但是,一些设置(连接字符串等)存在于通过 Startup.cs 注入的 appsettings.json 文件中。我如何在 NUnit 类中访问这些?

我的 Startup.cs,获取连接字符串并为 DI 做准备

public void ConfigureServices(IServiceCollection services)
{
    //other Configurations happen here

    //get the connection string values from appsettings.json
    services.Configure<ConnectionStrings>(Configuration.GetSection("ConnectionStrings"));

    //Classes that get DI'd
    services.AddSingleton<IMyDAL, MyDal>();
    services.AddSingleton<MyBLL>();
}

MyDAL 需要注入配置,可通过 Startup.cs 获得:

public class MyDAL : IMyDAL
{
    private readonly string _dbConnectionString;

    public MyDAL(IOptions<ConnectionStrings> connectionString)
    {
        _dbConnectionString = connectionString.Value.ConnectionString;
    }

    public bool DoDALStuff() { ... }
}

MyBLL 类需要注入 IMyDAL:

public class MyBLL
{
    public readonly IMyDAL _myDAL;

    public MyBLL(IMyDAL myDAL)
    {
        _myDAL = myDAL;
    }

    public bool DoBLLStuff() { ... }        
}

我的 NUnit 类需要 BLL 注入来测试:

[TestFixture]
public class BLLTest
{
    public MyBLL _myBLL;

    public BLLTest(MyBLL myBLL)
    {
        _myBLL = myBLL;
    }

    [Test]
    public void TestTheBLL()
    {
        Assert.IsTrue(_myBLL.DoBLLStuff() == true)
    }
}

这就是我的常规程序流程的样子,但我可能会以错误的方式接近它,试图以相同的 DI 方式实现此单元测试。如果我删除测试类中的任何 DI/构造函数代码,测试运行良好,但我仍然需要在 BLL 中测试需要 DI 的方法。任何人都知道如何将 DI 对象放入我的测试类中使用?我是否使用了不正确的方法?

【问题讨论】:

    标签: c# asp.net-core nunit asp.net-core-mvc


    【解决方案1】:

    我是否使用了不正确的方法?

    是的。您误解了单元测试的定义。您想单独测试 BLL。不反对实际实现,因为那将是一个集成测试。

    如何将 DI 对象放入我的测试类中使用?

    您创建依赖项的虚假实现或使用您选择的模拟框架来模拟单元测试的依赖项。

    [TestFixture]
    public class BLLTest {
        private MyBLL _myBLL;
    
        public BLLTest() {
            //Arrange        
            var dalMock = new Mock<IMyDAL>();
            dalMock.Setup(x => x.DoDALStuff()).Returns(true);//setup expected behavior
            //...setup other expected behavior of dependencies
    
            //create the target of unit test (class under test)
            _myBLL = new MyBLL(dalMock.Object); //manually injecting dependency
        }
    
        [Test]
        public void TestTheBLL() {
            //Act
            var result = _myBLL.DoBLLStuff();
            //Assert
            Assert.IsTrue(result);
        }
    }
    

    这只是一个让您入门的基本示例。还有很多其他方法可以做到这一点。你应该对单元测试做更多的研究

    【讨论】:

    • 迟到的答案,但我最终像你所说的那样嘲笑并且有效。我可能误解了单元测试框架中的依赖注入能力。谢谢!
    【解决方案2】:

    我正在使用 xUnit,我还没有时间深入研究 Nunit。

    警告 (source)

    dotnet-test-nunit 仍然是 alpha 版本

    我相信您的测试运行程序有问题。你应该从阅读Integration testing with ASP.NET Core 开始。示例仅适用于 xUnit。

    这里还有一个blog post 如何使用 Nunit 执行此操作。

    重要的是您运行您的测试项目,而不是直接运行您的网络项目(即使这个项目被测试项目引用和使用)。

    因此,您需要在您的测试项目中使用另一个 JSON 设置文件,该文件将用于代替您的 Web 项目中的那个。您当然希望在测试模式下进行其他配置,而不是在 Dev 或 Prod 中。

    如果进行单元测试,您更愿意直接调用类的方法,但如果您处于集成测试环境中,则应该像任何其他客户端(JavaScript、移动应用程序...等)一样调用您的控制器。

    为此,您可以创建 TestServer,然后从您的客户端创建一个客户端,最后发送正常的 HTTP 请求,如下所示:

    var webHostBuilder = new WebHostBuilder().UseEnvironment("Testing").UseStartup<Startup>();
    var host = new TestServer(webHostBuilder);
    var client = host.CreateClient();
    var response = await client.PostAsync(endpoint, form);
    

    在这个例子中,endpoint 就是这个 URL,form 是一个MultipartFormDataContent,因为我要发布一个文件

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-10
      • 2011-01-11
      相关资源
      最近更新 更多