简体   繁体   English

带有构造函数注入的单元测试ASP.NET MVC控制器

[英]Unit testing asp.net MVC controller with constructor injection

How do i setup my test project so that i can unit test my controllers, I'm not able to call my controller actions from test method as it requires dependent interface object. 我如何设置我的测试项目,以便可以对控制器进行单元测试,所以我无法从测试方法中调用控制器动作,因为它需要依赖的接口对象。 I don't want to implement any mock repository. 我不想实现任何模拟存储库。 I want to use my existing database repository and business logic available same as integration testing. 我想使用与集成测试相同的现有数据库存储库和业务逻辑。

My Project Structure is as below: 我的项目结构如下:

  • MVC.Web 网站
  • MVC.BL (Interface and implementation) MVC.BL(接口和实现)
  • MVC.Repository (Interface and implementation) MVC.Repository(接口和实现)

Repository Example: 储存库示例:

public class UserRepository : IUserRepository
{
    private readonly IBaseUOW<DBEntitiesEntities> _dbContext;
    private readonly IBaseRepository<User> _userRepository;

    public UserRepository(IBaseUOW<MoynoECTNewEntities> dbContext)
    {
        _dbContext = dbContext;
        _userRepository = dbContext.GetRepository<User>();
    }

    public UserResponse GetUserList()
    {
        var response = new UserResponse {Acknowledge = AcknowledgeType.Success};

        var typeList = _userRepository.Get().OrderBy(x => x.UserName).ToList();

        response.UserList = typeList.ToList();

        return response;
    }
}

Business Layer Example: 业务层示例:

public class UserBL : IUserBL
{
    public UserResponse GetUserList()
    {
        var response = new UserResponse();

        var userList = _userRepository.GetUserList();
        if (userList != null && userList.UserList.Count > 0)
        {
            response.UserList = userList.UserList.ToList();
        }
        else
        {
            response.Message = "No Data Found";
            response.Acknowledge = AcknowledgeType.Failure;
        }

        return response;
    }
}

Controller Example: 控制器示例:

public class AdminController : BaseController
{
    public readonly IUserBL _userBl;
    public readonly IUserRoleBL _userRoleBl;

    public AdminController(IUserRoleBL userRoleBl, IUserBL userBl)
    {
        _userRoleBl = userRoleBl;
        _userBl = userBl;
    }

    public ActionResult GetUserList()
    {
        var response = _userBl.GetUserList();
        return View("_GridViewUser", response.UserList);
    }
}

My unit test method example: 我的单元测试方法示例:

[TestClass]
public class AdminControllerTest
{

    [TestMethod]
    public void Check_UserMaster_ViewName()
    {
       //assemple
        var controller = // how to call controller ?
       // act
        var result= // controller.GetUserList() as ViewResult;
       // assert
        Assert.AreEqual("UserMaster", result.ViewName);
    }
}

I don't want to implement mock repository and directly want to use my existing database repository 我不想实现模拟存储库,而直接想使用我现有的数据库存储库

Well I think that's the wrong approach since you're unit testing the class, meaning all dependencies should not impact the validity of the test, but that's your call. 好吧,我认为这是错误的方法,因为您正在对类进行单元测试 ,这意味着所有依赖项都不会影响测试的有效性,但这就是您的要求。

Just pass in an instance of the "real" repository in your test. 只需在测试中传递“真实”存储库的实例即可。

var userRoleBL = new UserBL();
var userBL = new UserRoleBL();
var controller = new AdminController(userRoleBL, userBL);
// test the controller

As @D Stanley said, you should only test that the Controller returns the appropriate result, not that the other layers, database etc. are working. 正如@D Stanley所说,您应该只测试Controller返回适当的结果,而不测试其他层,数据库等是否正常工作。

However, to create the Controller in a Unit Test use: 但是,要在单元测试中创建控制器,请使用:

var controller = new AdminController(any arguments/contexts here);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM