且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-02-17 07:53:05

更新:xUnit 仍然是一个好主意,但是这个答案现在已经过时了,因为您可以 也使用标准"如果您想要 ASP.NET 核心,请使用 MSTEST.(2016 年 6 月 1 日)我发现我仍然更喜欢 xUnit,但这取决于您.

最新的 xUnit 说明链接:在 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 一起使用]2 位于 xUnit GitHub 项目中,该项目具有特定的.NET Core 入门";案例.

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

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

https://bitbucket.org/wpostma/aspnet5mvc6xunitdemo

如果您没有 Mercurial,您可以下载 ZIP 来自 Bitbucket 的文件.

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

快速总结:

  1. 您拥有 Visual Studio 2015,包括 Update 2 和1.0.0 预览版"工具(最新于 2016 年 5 月).

  2. 创建一个Web 类库不是单元测试项目.

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

  4. 编写您的类(下面的示例).

  5. 在 IDE 内或在 IDE 外使用测试资源管理器运行测试,输入 dnx .测试,并检查输出(下面的例子).

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

 {版本":1.0.0-*",testRunner":xunit",依赖关系":{Microsoft.NETCore.App":{版本":1.0.0-rc2-3002702",类型":平台"},dotnet-test-xunit":1.0.0-rc2-*",xunit":2.1.0",YetAnotherWebbyDemo":1.0.0-*"},框架":{netcoreapp1.0":{进口":[dotnet5.6",dnxcore50",《便携-net45+win8》]}}}

单元测试类(whatever.cs):

使用系统;使用 System.Collections.Generic;使用 System.Linq;使用 System.Threading.Tasks;使用 Xunit;使用 YetAnotherWebbyDemo.Models;命名空间 YetAnotherWebbyDemoTests{//该项目可以将类库输出为 NuGet 包.//要启用此选项,请右键单击项目并选择属性"菜单项.在构建"选项卡中,选择在构建时生成输出".公共类 TestBasics{[事实]公共无效测试添加(){TestableModelClass TestMe = new TestableModelClass();Assert.True(TestMe.Add(3, 2) == 5, 基础数学失败");Assert.True(TestMe.Add(-3, -2) == -5, 基础数学失败");}}}

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

C:devDemoYetAnotherWebbyDemosrcYetAnotherWebbyDemoTests>dnx.测试xUnit.net DNX Runner(32 位 DNX 4.5.1)发现:YetAnotherWebbyDemoTests发现:YetAnotherWebbyDemoTests开始:YetAnotherWebbyDemoTestsYetAnotherWebbyDemoTests.TestBasics.TestAdd [失败]基本数学失败预期:真实实际:错误堆栈跟踪:YetAnotherWebbyDemoTestBasics.cs(25,0):在 YetAnotherWebbyDemoTests.TestBasics.TestAdd()完成:YetAnotherWebbyDemoTests=== 测试执行摘要 ===YetAnotherWebbyDemoTests 总计:1,错误:0,失败:1,跳过:0,时间:0.263s

我们使用 dotnet 的 RC2 输出示例:

D:devaspnet5mvc6xunitdemosrcYetAnotherWebbyDemoTests>dotnet testProject YetAnotherWebbyDemo (.NETCoreApp,Version=v1.0) 之前已编译.跳过编译.Project YetAnotherWebbyDemoTests (.NETCoreApp,Version=v1.0) 之前已编译.跳过编译.xUnit.net .NET CLI 测试运行程序(64 位 win10-x64)发现:YetAnotherWebbyDemoTests发现:YetAnotherWebbyDemoTests开始:YetAnotherWebbyDemoTestsYetAnotherWebbyDemoTests.TestBasics.TestAdd [失败]基本数学失败预期:真实实际:错误堆栈跟踪:D:devaspnet5mvc6xunitdemosrcYetAnotherWebbyDemoTestsYetAnotherWebbyDemoTestBasics.cs(26,0): at YetAnotherWebbyDemoTests.TestBasics.TestAdd()完成:YetAnotherWebbyDemoTests=== 测试执行摘要 ===YetAnotherWebbyDemoTests 总计:1,错误:0,失败:1,跳过:0,时间:0.205s总结:总计:1 个目标,通过:0,失败:1.

I am trying to get some controller, model, and repository (data access) C# classes under unit test, in Visual Studio 2015, with ASP.NET Core MVC (ASP.NET 5 during the preview, now called ASP.NET Core) applications.

I have the following structure:

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

The MainApp is using DNX 4.5.1, but it seems that if I create a standard NUnit Unit test application, it's only available as a classic .NET Framework class library, targetting .NET Framework 4.5.2, not as a Web Class Library that can work with my main application.

So, just in case it might work as a classic .NET framework Microsoft Unit Test framework project (.NET assembly), I tried to manually find and add references (by add reference, and browse) to get the .NET dependencies to resolve. I am aware that .NET assembly references are sadly non-transitive. So if UnitTest.dll has a reference to MainApp.dll, and MainApp.dll depends on ASP.NET MVC, and everything else that it depends on, I have to do that myself. That is what I'm trying to do.

I added a reference to C:devDemoITConsoleartifactsinITConsoleDebugdnx451ITConsole.dll into my unit test project so I could begin to get the code to compile. The unit test classes compile, but they don't run, probably because of the mess of trying to add a reference to ASP.NET.

Right now, even though I have added a reference to Common.Logging.Core, and Common.Logging, when I click "Run All" on the Test explorer I get this error:

Test Name:    TestStudyLogReadDocument
Test FullName:    ITConsoleTests.ITConsoleTestStudyLog.TestStudyLogReadDocument
Test Source:    C:devDemoITConsoleITConsoleTestsITConsoleTestStudyLog.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:devDemoITConsolesrcITConsoleRepositoryStudyLogRepository.cs:line 39
   at ITConsoleTests.ITConsoleTestStudyLog.SetupDb() in C:devDemoITConsoleITConsoleTestsITConsoleTestStudyLog.cs:line 30
   at ITConsoleTests.ITConsoleTestStudyLog.TestStudyLogReadDocument() in C:devDemoITConsoleITConsoleTestsITConsoleTestStudyLog.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)

(At the time this question was asked...) None of the ASP.NET 5 MVC preview templates can generate unit tests for you. Can you even unit test a shiny new ASP.NET Core application? See screenshot below, for example of how the normal way you get started unit testing is not available in Visual Studio 2015 using MSTEST.

Update: xUnit is still a great idea, but this answer is outdated now because you can also use the "standard" MSTEST if you want with ASP.NET core. (June 1, 2016) I find I still prefer xUnit, but it's your call.

Most recent xUnit instructions link: Excellent instructions that may be updated more often than this answer are found at the xUnit wiki.

IDE workaround: manually find and delete %TEMP%VisualStudioTestExplorerExtensions when Visual Studio goes stupid and won't "detect" and show you your tests.

As of May 2016, with ASP.NET Core 1.0 RC1 recently superseded by RC2, it still does not appear possible to use the standard Microsoft Unit Test framework with ASP.NET Core (formerly ASP.NET 5), and xUnit appears to be a good choice for RC1 and RC2.

You can get XUnit.net unit testing to work with ASP.NET Core 1.0.0-RC1, using the official instructions]2 at the xUnit GitHub project which has a specific ".NET Core getting started" case.

You can also install the xUnit new project template that provides a templated unit test project for regular full .NET and .NET Core. Click menu Tools and then Extensions and Updates type in xUnit, and find the xUnit Test Project template and install the template. Do not install any xUnit test runner; you do not need it..

I have created a working sample and uploaded it to Bitbucket:

https://bitbucket.org/wpostma/aspnet5mvc6xunitdemo

If you don't have Mercurial, you can download a ZIP file from Bitbucket.

The demo includes one test that passes, and one test that fails.

The Quick Summary:

  1. You have Visual Studio 2015 including Update 2 and the "1.0.0 preview" tools (latest as of May 2016).

  2. Create a Web Class Library, not a Unit Test Project.

  3. Add xUnit references to it, and fix your project.json (an example is below).

  4. Write your class (example below).

  5. Run tests with Test Explorer inside the IDE, or outside IDE, type in dnx . tests, and examine the output (example below).

File project.json for 1.0.0-rc2 with reference to a demo assembly and 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"
      ]
    }
  }
}

Unit test 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");
        }

    }
}

Example output from commandline in RC1 when we used dnx:

C:devDemoYetAnotherWebbyDemosrcYetAnotherWebbyDemoTests>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

Example output in RC2 where we're using dotnet:

D:devaspnet5mvc6xunitdemosrcYetAnotherWebbyDemoTests>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:devaspnet5mvc6xunitdemosrcYetAnotherWebbyDemoTestsYetAnotherWebbyDemoTestBasics.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.