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

22
我想在Visual Studio 2015中对ASP.NET Core MVC(预览时称为ASP.NET 5)应用程序下的控制器、模型和存储库(数据访问)C#类进行单元测试。
我有以下结构:
   Solution
       |
      src
       |
       |-- ITConsole       <- main app (ASP.NET MVC, DNX 4.5.1)
       |
       `-- ITConsoleTests  <- What kind of project should this be?

MainApp正在使用DNX 4.5.1,但是如果我创建一个标准的NUnit单元测试应用程序,它只作为一个经典的.NET Framework类库可用,目标为.NET Framework 4.5.2,并不作为Web类库,无法与我的主应用程序一起工作。
因此,以防万一它可能作为一个经典的.NET framework Microsoft Unit Test framework项目(.NET程序集)工作,我尝试手动查找和添加引用(通过添加引用和浏览),以获得.NET依赖项来解决。我知道.NET程序集引用很遗憾地无法传递。所以如果UnitTest.dll引用MainApp.dll,而MainApp.dll依赖于ASP.NET MVC和其他所有依赖项,我必须自己完成。这就是我正在尝试做的事情。
我添加了一个对C:\dev\Demo\ITConsole\artifacts\bin\ITConsole\Debug\dnx451\ITConsole.dll的引用到我的单元测试项目中,以便我可以开始编译代码。单元测试类编译通过,但它们不运行,可能是因为试图添加对ASP.NET的引用而导致混乱。

现在,尽管我已经添加了对Common.Logging.Core和Common.Logging的引用,但当我在测试资源管理器上单击“运行全部”时,我收到以下错误:

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预览模板都无法为您生成单元测试。您甚至可以对全新的ASP.NET Core应用程序进行单元测试吗?例如,如下屏幕截图所示,使用MSTEST在Visual Studio 2015中开始进行单元测试的常规方式不可用。

No unit test for you


在这里提问“你们什么时候修复你们的产品”问题:https://social.msdn.microsoft.com/Forums/vstudio/en-US/6bf553bc-2bbb-4f2e-a7aa-72c8d9b74852/when-will-i-be-able-to-unit-test-in-visual-studio-2015-with-aspnet-mvc6?forum=vsunittest - Warren P
我相信这将在9月中旬Beta8推出时开始运作。 - Warren P
1
同时,也许可以尝试这个链接:http://xunit.github.io/docs/getting-started-dnx.html - Warren P
与NUnit相关的内容,但是关于xUnit:http://stackoverflow.com/questions/31121523/not-able-to-use-tests-in-asp-net-vnext-and-visual-studio-2015?rq=1 - Warren P
3个回答

17

更新:xUnit仍然是一个很好的选择,但是这个答案已经过时了,因为你也可以在ASP.NET Core中使用标准MSTEST。 (2016年6月1日) 我发现我仍然更喜欢xUnit,但这取决于你。

最新的xUnit指令链接优秀的指令可能比这个答案更新,请参考xUnit wiki。

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

截至2016年5月,由于ASP.NET Core 1.0 RC1最近被RC2取代,似乎仍无法使用标准的Microsoft Unit Test框架与ASP.NET Core(原名ASP.NET 5),因此xUnit似乎是RC1和RC2的不错选择。

您可以使用官方指令2将XUnit.net单元测试与ASP.NET Core 1.0.0-RC1一起使用,该指令位于xUnit GitHub项目中,具有特定的“.NET Core入门”示例。

您也可以安装xUnit新项目模板,为常规完整的.NET和.NET Core提供一个模板化的单元测试项目。点击菜单工具,然后扩展和更新,输入xUnit,找到xUnit Test Project template并安装template不要安装任何xUnit test runner;您不需要它。

我创建了一个可用的示例,并将其上传到Bitbucket

https://bitbucket.org/wpostma/aspnet5mvc6xunitdemo

如果您没有Mercurial,您可以从Bitbucket下载一个ZIP文件。

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

快速摘要:

  1. 您拥有带有Update 2和“1.0.0 preview”工具(截至2016年5月)的Visual Studio 2015。

  2. 创建一个Web Class Library,而不是Unit Test Project

  3. 将xUnit引用添加到其中,并修复您的project.json(以下是一个示例)。

  4. 编写您的类(以下是一个示例)。

  5. 使用IDE内部的Test Explorer运行测试,或在IDE外部键入dnx . tests并检查输出(以下是一个示例)。

文件project.json用于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"
      ]
    }
  }
}

单元测试类(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.

我按照你的步骤操作,一切都很顺利!需要注意的是:为了更新我的project.json文件,我从原始项目中复制了“frameworks”,并从你的示例中复制了“commands”。保存并还原包后,我可以在测试项目中添加对该项目的引用。然后,我通过nuget添加了xunit和xunit.runner.dnx(必须包括预览版本)。 - Daniel Albuschat
是的,说得好。我的例子只适用于使用我正在使用的框架的人。我这里只列出了dnx451,因为在我的情况下,我有一些依赖项无法与coreclr一起使用。 - Warren P
你的 TestableModelClass 包括控制器类吗? - dumbledad
对于XUnit测试运行器的依赖,您应该使用:"dotnet-test-xunit": "1.0.0-rc2-*"。在此示例中使用的版本(1.0.0-rc2-build10015)在针对net461时存在重大错误。 - Geo
没错。已修复。 - Warren P
1
这里有一个关于.NET Core 1.0 RTM中MSTest的更新文章:https://blogs.msdn.microsoft.com/visualstudioalm/2016/09/01/announcing-mstest-v2-framework-support-for-net-core-1-0-rtm/ - ajbeaven

2

链接已经失效了,兄弟。 - carloswm85

-1

随着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);
    }
}

1
它可以在RC2上工作。请查看我的更新答案。无需切换到NUNIT。 - Warren P
1
沃伦,我的项目使用net 4.6.1和xunit测试运行器的版本“dotnet-test-xunit”:“1.0.0-rc2-build10015”在net461上崩溃了。我参考了这个bug:https://github.com/dotnet/cli/issues/3103 尽管如此,构建10025解决了这个特定的bug,并且从控制台和VS2015中运行良好。所以现在我回到XUnit。 - Geo
目前来看,NUNIT在ASP.NET Core上并不是一个好的选择。但希望在3.4+版本中会有所改善。https://github.com/nunit/nunit/issues/1555 - Warren P

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接