如何对 ASP.NET 核心控制器或模型对象进行单元测试?

How do you unit test an ASP.NET Core controller or model object?

我正在尝试在 Visual Studio 2015 年使用 ASP.NET 核心 MVC(ASP.NET 5 在预览期间,现在称为 ASP.NET 核心) 应用程序。

我有以下结构:

   Solution
       |
      src
       |
       |-- ITConsole       <- main app (ASP.NET MVC, DNX 4.5.1)
       |
       `-- ITConsoleTests  <- What kind of project should this be?

MainApp 使用 4.5.1,但似乎如果我创建一个标准的 NUnit 单元测试应用程序,它只能作为 classic .NET Framework class 库,以 .NET Framework 4.5.2 为目标,而不是作为 Web Class 可以与我的主应用程序一起使用的库。

因此,以防万一它可能作为 classic .NET 框架 Microsoft 单元测试框架项目(.NET 程序集)工作,我尝试手动查找和添加引用(通过添加引用,然后浏览) 来获取要解析的 .NET 依赖项。我知道 .NET 程序集引用很遗憾是不可传递的。因此,如果 UnitTest.dll 引用了 MainApp.dll,并且 MainApp.dll 依赖于 ASP.NET MVC,以及它依赖的所有其他内容,我必须自己做。这就是我想要做的。

我在我的单元测试项目中添加了对 C:\dev\Demo\ITConsole\artifacts\bin\ITConsole\Debug\dnx451\ITConsole.dll 的引用,这样我就可以开始编译代码了。单元测试 class 可以编译,但它们不会 运行,可能是因为尝试添加对 ASP.NET.

的引用时一团糟

现在,即使我添加了对 Common.Logging.Core 和 Common.Logging 的引用,当我在测试资源管理器上单击 "Run All" 时,我仍收到此错误:

Test Name:    TestStudyLogReadDocument
Test FullName:    ITConsoleTests.ITConsoleTestStudyLog.TestStudyLogReadDocument
Test Source:    C:\dev\Demo\ITConsole\ITConsoleTests\ITConsoleTestStudyLog.cs : line 52
Test Outcome:    Failed
Test Duration:    0:00:00.0712058

Result StackTrace:
at Couchbase.Configuration.Client.ClientConfiguration..ctor()
   at ITConsole.Repository.StudyLogRepository..ctor() in C:\dev\Demo\ITConsole\src\ITConsole\Repository\StudyLogRepository.cs:line 39
   at ITConsoleTests.ITConsoleTestStudyLog.SetupDb() in C:\dev\Demo\ITConsole\ITConsoleTests\ITConsoleTestStudyLog.cs:line 30
   at ITConsoleTests.ITConsoleTestStudyLog.TestStudyLogReadDocument() in C:\dev\Demo\ITConsole\ITConsoleTests\ITConsoleTestStudyLog.cs:line 53
Result Message:
Test method ITConsoleTests.ITConsoleTestStudyLog.TestStudyLogReadDocument threw exception:
System.IO.FileLoadException: Could not load file or assembly 'Common.Logging.Core, Version=3.1.0.0, Culture=neutral, PublicKeyToken=af08829b84f0328e' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

(当时问这个问题...)ASP.NET 5 MVC 预览模板中的None 可以为您生成单元测试。您甚至可以对闪亮的新 ASP.NET 核心应用程序进行单元测试吗?请参阅下面的屏幕截图,例如如何使用 MSTEST 在 Visual Studio 2015 中使用单元测试的正常入门方式。

更新:xUnit 仍然是一个好主意,但这个答案现在已经过时了,因为你可以 also use the "standard" MSTEST if you want with ASP.NET core。 (2016 年 6 月 1 日)我发现我仍然更喜欢 xUnit,但这是你的决定。

最近的 xUnit 指令linkExcellent instructions that may be updated more often than this answer are found at the xUnit wiki.

IDE 解决方法:当 Visual Studio 变得愚蠢时手动查找并删除 %TEMP%\VisualStudioTestExplorerExtensions不会“检测”并向您展示您的测试。

截至 2016 年 5 月,ASP.NET Core 1.0 RC1 最近被 RC2 取代,似乎仍然无法将标准 Microsoft 单元测试框架与 ASP.NET Core(以前的 ASP.NET 5),xUnit 似乎是 RC1 和 RC2 的不错选择。

您可以获得 XUnit.net 单元测试以使用 ASP.NET Core 1.0.0-RC1,使用 xUnit GitHub 项目中的官方说明]2有一个特定的“.NET Core 入门”案例。

您还可以安装 xUnit 新项目模板,它为常规的完整 .NET 和 .NET Core 提供模板化的单元测试项目。单击菜单 Tools 然后 Extensions and Updates 输入 xUnit,然后找到 xUnit Test Project template 和安装 模板 不要安装任何 xUnit 测试运行器;你不需要它。.

我创建了一个工作示例并将其上传到 Bitbucket:

https://bitbucket.org/wpostma/aspnet5mvc6xunitdemo

如果您没有来自 Bitbucket 的 Mercurial, you can download a ZIP 文件。

该演示包括一项通过的测试和一项失败的测试。

快速总结:

  1. 您有 Visual Studio 2015,包括更新 2 和“1.0.0 预览版”工具(截至 2016 年 5 月最新)。

  2. 创建 Web Class 库, not 单元测试项目

  3. 向其添加 xUnit 引用,并修复您的 project.json(示例如下)。

  4. 写下您的 class(示例如下)。

  5. 运行 在 IDE 内或 IDE 外使用 Test Explorer 进行测试,输入 dnx . tests,然后检查输出(下面的示例).

File project.json for 1.0.0-rc2 参考演示程序集和 xUnit:

 {
  "version": "1.0.0-*",

  "testRunner": "xunit",

  "dependencies": {
    "Microsoft.NETCore.App": {
      "version": "1.0.0-rc2-3002702",
      "type": "platform"
    },

    "dotnet-test-xunit": "1.0.0-rc2-*",

    "xunit": "2.1.0",


    "YetAnotherWebbyDemo": "1.0.0-*"
  },

  "frameworks": {
    "netcoreapp1.0": {
      "imports": [
        "dotnet5.6",
        "dnxcore50",
        "portable-net45+win8"
      ]
    }
  }
}

单元测试class (whatever.cs):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

using Xunit;

using YetAnotherWebbyDemo.Models;

namespace YetAnotherWebbyDemoTests
{
    // This project can output the Class library as a NuGet Package.
    // To enable this option, right-click on the project and select the Properties menu item. In the Build tab select "Produce outputs on build".
    public class TestBasics
    {
        [Fact]
        public void TestAdd()
        {

            TestableModelClass TestMe = new TestableModelClass();


            Assert.True(TestMe.Add(3, 2) == 5, "Basic Math Failure");

            Assert.True(TestMe.Add(-3, -2) == -5, "Basic Math Failure");
        }

    }
}

我们使用 dnx 时 RC1 中命令行的示例输出:

C:\dev\Demo\YetAnotherWebbyDemo\src\YetAnotherWebbyDemoTests>dnx . test

xUnit.net DNX Runner (32-bit DNX 4.5.1)
  Discovering: YetAnotherWebbyDemoTests
  Discovered:  YetAnotherWebbyDemoTests
  Starting:    YetAnotherWebbyDemoTests
    YetAnotherWebbyDemoTests.TestBasics.TestAdd [FAIL]
      Basic Math Failure
      Expected: True
      Actual:   False
      Stack Trace:
        YetAnotherWebbyDemoTestBasics.cs(25,0): at YetAnotherWebbyDemoTests.Test
Basics.TestAdd()
  Finished:    YetAnotherWebbyDemoTests
=== TEST EXECUTION SUMMARY ===
   YetAnotherWebbyDemoTests  Total: 1, Errors: 0, Failed: 1, Skipped: 0, Time: 0.263s

我们使用 dotnet:

的 RC2 示例输出
D:\dev\aspnet5mvc6xunitdemo\src\YetAnotherWebbyDemoTests>dotnet test
Project YetAnotherWebbyDemo (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation.
Project YetAnotherWebbyDemoTests (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation.
xUnit.net .NET CLI test runner (64-bit win10-x64)
  Discovering: YetAnotherWebbyDemoTests
  Discovered:  YetAnotherWebbyDemoTests
  Starting:    YetAnotherWebbyDemoTests
    YetAnotherWebbyDemoTests.TestBasics.TestAdd [FAIL]
      Basic Math Failure
      Expected: True
      Actual:   False
      Stack Trace:
        D:\dev\aspnet5mvc6xunitdemo\src\YetAnotherWebbyDemoTests\YetAnotherWebbyDemoTestBasics.cs(26,0): at YetAnotherWebbyDemoTests.TestBasics.TestAdd()
  Finished:    YetAnotherWebbyDemoTests
=== TEST EXECUTION SUMMARY ===
   YetAnotherWebbyDemoTests  Total: 1, Errors: 0, Failed: 1, Skipped: 0, Time: 0.205s
SUMMARY: Total: 1 targets, Passed: 0, Failed: 1.

xUnit 团队在更新他们的文档方面做得很好。

为了始终更新信息,请参阅 xUnit 文档,网址为:

Getting Started with xUnit.net

随着 RC2 的发布,xUnit 集成不再适用于我的项目(此问题现已修复,请参阅评论)。为了能够测试我的项目,我切换到 NUnit。它似乎支持 RC2 并且有一个轻量级的测试运行器 NUnitLite。

基本上您需要将 NUnitLite 托管到控制台应用程序中并使用 "dotnet run" 启动它。

添加以下依赖项:

"dependencies": {
    "NUnit": "3.2.1",
    "NUnitLite": "3.2.1",

要启动测试运行程序,您需要将此代码添加到 program.cs 文件中:

public class Program
{
    public static void Main(string[] args)
    {
        new AutoRun().Execute(args);
    }
}