ASP.NET MVC 2 单元测试阶段错误
Posted
技术标签:
【中文标题】ASP.NET MVC 2 单元测试阶段错误【英文标题】:ASP.NET MVC 2 Unit Testing Stange Errors 【发布时间】:2010-08-17 06:55:46 【问题描述】:我正在阅读 Professional ASP.NET MVC 2 这本书,并且我正在尝试让第 1 章中的单元测试正常工作;但是,我遇到了一些非常奇怪的错误。
解决方案中有两个项目:NerdDinner 和 NerdDinner.Tests。
在 NerdDinner 项目中我有以下界面:
IDinnerRepository.cs
//...
namespace NerdDinner.Models
interface IDinnerRepository
//...
同样在 NerdDinner 项目中,我有以下类:
//...
using NerdDinner.Models;
//...
namespace NerdDinner.Controllers
public class DinnersController : Controller
IDinnerRepository dinnerRepository;
// Default constructor
public DinnersController() : this(new DinnerRepository()) // DinnerRepository is another concrete implementation of IDinnerRepository
//Test constructor
public DinnersController(IDinnerRepository repository)
dinnerRepository = repository;
在 NerdDinner.Tests 项目中,我有以下 IDinnerRepository 的具体实现:
//...
using NerdDinner.Models;
//...
namespace NerdDinner.Tests.Fakes
class FakeDinnerRepository : IDinnerRepository
//...
public FakeDinnerRepository(List<Dinner> dinners)
//...
//...
现在进行实际的单元测试(在 NerdDinner.Tests 中)
using NerdDinner.Controllers;
//...
using NerdDinner.Models;
using NerdDinner.Tests.Fakes;
namespace NerdDinner.Tests
[TestClass]
public class DinnersControllerTest
List<Dinner> CreateTestDinners()
//...
DinnersController CreateDinnersController()
return new DinnersController(new FakeDinnerRepository(CreateTestDinners()));
现在针对实际问题: 在 DinnerControllerClass 类的 CreateDinnersController 方法中,出现以下错误:
DinnersController.DinnersController(NerdDinner.Models.IDinnerRepository 存储库)(+ 1 个重载) 错误: 'NerdDinner.Controllers.DinnersController.DinnersController(NerdDinner.Models.IDinnerRepository)' 的最佳重载方法匹配有一些无效参数。
它让我可以选择在 DinnersController 中创建构造函数存根。它生成以下代码:
private global::NerdDinner.Tests.Fakes.FakeDinnerRepository repository;
//...
public DinnersController(global::NerdDinner.Tests.Fakes.FakeDinnerRepository repository)
// TODO: Complete member initialization
this.repository = repository;
即使在生成该代码之后,我仍然会遇到同样的错误。但是为什么我还需要那个代码呢?据我所知,我做的一切都是正确的。
谁能帮我弄清楚这里发生了什么?
编辑 生成的代码给出以下错误:
命名空间“NerdDinner”中不存在类型或命名空间“Tests”(您是否缺少任何程序集引用?)
【问题讨论】:
【参考方案1】:从您所显示的情况来看,IDinnerRepository
界面是不公开的,这意味着它在您的单元测试中不可见。我建议您将其公开,因为我怀疑您有两种不同的接口:一种在单元测试中定义,另一种在您的项目中定义,但存在冲突。另外,我建议您避免依赖 Visual Studio 生成所有垃圾反射代码来测试私有和内部成员。
【讨论】:
我公开了界面,但我仍然遇到同样的错误。更正:错误不再存在。谢谢! @KPthunder:如果该接口以前不公开,您是如何设法在您的测试项目中实现它的?这就是为什么我建议检查“去定义”会带你去哪里...... @Jon Skeet:我刚刚输入了代码,它就起作用了。在我输入接口名称后,IDE 正在为我输入方法。我目前没有在这台计算机上安装 resharper,你认为 resharper 会发现这个吗? @KPthunder:我不确定,但您应该注意 IDE 正在为您做什么 - 接口必须以某种方式进入测试项目,并且你应该对此非常警惕。 @Jon Skeet:我不认为该界面在测试项目中,因为当我在未公开时按 F12 时,它会将我带到非测试项目中的界面。 【参考方案2】:您遇到的最后一个错误是由于没有从生产代码引用到测试代码 - 但这是适当的。你不想要那个额外的构造函数。
相反,您需要找出为什么没有使用采用IDinnerRepository
的现有构造函数。你确定你只有一个叫IDinnerRepository
的接口吗?如果你去FakeDinnerRepository
源,去声明,把光标放在IDinnerRepository
然后按F12(去定义)它去正确的地方吗?
如果您向IDinnerRepository
添加一个新成员(只是为了测试:void Foo();
可以)是否会导致生产和假实现都无法编译?
【讨论】:
是的,F12 将我带到了 NerdDinner.Models 中的一个 IDinnerRepository。当我添加 void foo() 时,它迫使我将所有该方法应用于所有具体实现。以上是关于ASP.NET MVC 2 单元测试阶段错误的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET-MVC:数据库默认值会破坏单元测试的精神吗? [关闭]
MVC 自定义过滤器,手动调用 ASP.NET 管道事件进行单元测试
在 ASP.NET Core MVC API 控制器上对 AuthorizeAttribute 进行单元测试