gpt4 book ai didi

c# - ASP.NET MVC Controller 单元测试失败

转载 作者:行者123 更新时间:2023-12-02 13:25:50 25 4
gpt4 key购买 nike

我尝试测试我的 Controller

[TestMethod]
public void Index()
{
AdminController controller = new AdminController();
ViewResult result = controller.Index() as ViewResult;
Assert.IsNotNull(result);
}

这是Index()代码:

public ActionResult Index()
{
var repository = new PostsRepository();
var posts = repository.GetAllPosts();

return View(posts);
}

存储库:

public class PostsRepository : IPostsRepository
{
PostsDataContext _dataContext = new PostsDataContext();

public IQueryable<Post> GetAllPosts()
{
var posts = from t in _dataContext.Posts select t;
return posts;
}

public Post GetPostById(int id)
{
var post = from t in _dataContext.Posts
where t.id == id
select t;
return post.First();
}
}

但是我的 Index() 单元测试失败并出现错误:

Test method MvcBlog.Tests.Controllers.AdminControllerTest.Index threw exception: 
System.NullReferenceException: Object reference not set to an instance of an object.

堆栈跟踪:

MvcBlog.Models.PostsDataContext..ctor() in C:\Users\cL1Nk3r\Documents\Visual Studio 2010\Projects\MvcBlog\MvcBlog\Models\Posts.designer.cs: line 38
MvcBlog.Repository.PostsRepository..ctor() in C:\Users\cL1Nk3r\Documents\Visual Studio 2010\Projects\MvcBlog\MvcBlog\Repository\PostsRepository.cs: line 11
MvcBlog.Controllers.AdminController.Index() in C:\Users\cL1Nk3r\Documents\Visual Studio 2010\Projects\MvcBlog\MvcBlog\Controllers\AdminController.cs: line 19
MvcBlog.Tests.Controllers.AdminControllerTest.Index() in C:\Users\cL1Nk3r\Documents\Visual Studio 2010\Projects\MvcBlog\MvcBlog.Tests\Controllers\AdminControllerTest.cs: line 19

为什么会出现错误?
如果我只是运行我的应用程序,它就可以正常工作。

源码下载:http://dl.dropbox.com/u/14053604/MvcBlog.rar

最佳答案

问题出在 Controller 操作中的以下行:

var repository = new PostsRepository();

在这里,您将 Controller 绑定(bind)到存储库的特定实现,这使得单独进行单元测试非常困难。为了在 Controller 和数据访问层之间实现较弱的耦合,我建议您使用构造函数注入(inject):

public class PostsController: Controller
{
private readonly IPostsRepository _repository;
public PostsController(IPostsRepository repository)
{
_repository = repository;
}

public ActionResult Index()
{
var posts = _repository.GetAllPosts();
return View(posts);
}
}

现在您的 Controller 与存储库的特定实现完全解耦,该存储库可能依赖于数据库等。现在您可以使用模拟框架,例如 Rhino MocksMoq为单元测试提供此存储库的虚拟实现。

我个人非常喜欢MVCContrib TestHelper它与 Rhino Mocks 配合使用,并允许对 Controller 操作进行非常优雅的单元测试。因此,一旦您将 Controller 与存储库的特定实现解耦(如我所示),您就可以进行以下单元测试:

[TestMethod]
public void PostsController_Index_Action_Should_Fetch_All_Posts_From_Repository()
{
// arrange
var postsRepositoryStub = MockRepository.GenerateStub<IPostsRepository>();
var sut = new PostsController(postsRepositoryStub);
var expectedPosts = new Post[0];
postsRepositoryStub.Stub(x => x.GetAllPosts).Return(expectedPosts);

// act
var actual = sut.Index();

// assert
actual
.AssertViewRendered()
.WithViewData<IEnumerable<Post>>()
.ShouldBe(expectedPosts);
}

关于c# - ASP.NET MVC Controller 单元测试失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4839459/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com