如何对ASP.NET Core控制器或模型对象进行unit testing?

我试图在Visual Studio 2015中使用ASP.NET Core MVC(预览期间的ASP.NET 5,现在称为ASP.Net Core)应用程序在unit testing下获得一些控制器,模型和存储库(数据访问)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 Unit测试应用程序,它只能用作经典的.NET Framework类库,目标是.NET Framework 4.5.2,而不是Web类库。可以使用我的主应用程序。

因此,为了防止它可能作为经典的.NET框架Microsoftunit testing框架项目(.net程序集)工作,我尝试手动查找和添加引用(通过添加引用和浏览)来获取要解析的.NET依赖项。 我知道.NET程序集引用很遗憾是不可传递的。 因此,如果UnitTest.dll具有对MainApp.dll的引用,并且MainApp.dll依赖于ASP.NET MVC以及它所依赖的所有其他内容,那么我必须自己执行此操作。 这就是我想要做的。 我将C:\dev\Demo\ITConsole\artifacts\bin\ITConsole\Debug\dnx451\ITConsole.dll到我的unit testing项目中,这样我就可以开始编译代码了。 unit testing类编译但它们不运行,可能是因为尝试添加对ASP.NET的引用。

现在,即使我添加了对Common.Logging.Core和Common.Logging的引用,当我在Test explorer上单击“全部运行”时,我收到此错误:

 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预览模板都不能为你生成unit testing。 你甚至可以单独测试一个shiny的新ASP.NET Core应用程序吗? 请参阅下面的屏幕截图,例如,使用MSTEST在VS 2015中无法使用正常的unit testing方法。

没有单位测试

更新:XUnit仍然是一个好主意,但这个答案现在已经过时,因为如果你想使用ASP.NET核心,你也可以使用“标准”MSTEST 。 (2016年6月1日)我发现我仍然喜欢XUnit,但这是你的电话。

最近的XUNIT说明链接: 在xUnit wiki上可以找到比这个答案更频繁更新的优秀说明。

IDE替代方法:当Visual Studio变为愚蠢并且不会“检测”并向您显示测试时,手动查找并删除%TEMP%\VisualStudioTestExplorerExtensions

截至2016年5月,最近被RC2取代的ASP.NET Core 1.0 RC1仍然无法使用标准的Microsoftunit testing框架与ASP.NET Core(以前的ASP.NET 5),而XUnit似乎是一个RC1和RC2的不错选择。

您可以使用XUnit github项目中的官方说明2来获得XUnit.netunit testing以使用ASP.NET Core 1.0.0-RC1,该项目具有特定的“.net核心入门”案例。

您还可以安装XUnit新项目模板 ,该模板为常规的完整.net和.net核心提供模板化unit testing项目。 单击工具,然后在XUnit中键入Extensions and Updates,找到xUnit Test Project TEMPLATE并安装TEMPLATE。 不要安装任何xUNIT TEST RUNNER,你不需要它。

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

https://bitbucket.org/wpostma/aspnet5mvc6xunitdemo

如果你没有mercurial,你可以从bitbucket下载一个zip。

该演示包括一个通过的测试,以及一个失败的测试。

快速摘要:

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

  2. 创建Web类库而不是unit testing项目。

  3. 添加XUnit引用,并修复project.json(下面的示例)。

  4. 写下你的课程(下面的例子)。

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

project.json for 1.0.0-rc2,参考了一个demo程序集和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 testing类(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文档:

http://xunit.github.io/docs/getting-started-dotnet-core.html

随着RC2的发布,Xunit集成对我的项目不起作用了(现在已经修复了看评论)。 为了能够测试我的项目,我切换到了NUnit。 它似乎支持RC2并且有一个轻量级的testrunner 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); } }