如何在asp.net mvc 4中单元测试具有membership.getuser的控制器操作

时间:2014-12-20 04:21:53

标签: asp.net-mvc-4 unit-testing

我是ASP.NET MVC的新手。您能否告诉我如何从下面的代码中获取Membership.GetUser?我搜索了不同的论坛,但没有得到我正在寻找的答案。我可能做错了什么。

private readonly IMyRepository _respository;
public class MyController
{
    public MyController() : this(new MyRepository())
    {

    }
    public MyController(IMyRepository myrepository)
    {
        _respository = myrepository;            
    }
    public ActionResult Index()
    {
        var todoList = _repository.GetAllTodoItems();
        if (todoList.Count() == 0)
            return Content("No Todo List Items found");
        else
        {                
            return View("List", todoList);
        }
    }
}
public class MyRepository
{
    public IEnumerable<CustomModel> GetAllTodoItems()
    {
        var userid = (int)Membership.GetUser().ProviderUserKey;
        var todoList = _dbcontext.CustomList.Where(e => e.UserId == userid);

        return todoList;
    }
}

有人可以提供详细的回复吗?

2 个答案:

答案 0 :(得分:0)

每当调用DateTime.Now()之类的静态方法时,都会使代码不可测试。 ...除非你使用像Typemock这样的隔离框架,它无法改变执行测试的运行时行为。

使用静态调用Membership的方法创建一些接口及其实现。

将此接口作为依赖项注入控制器。

然后在您的单元测试中,您将能够模拟此接口并检查调用或返回测试所需的值。

答案 1 :(得分:0)

我认为您没有正确使用它,因为您的存储库依赖于Membership.GetUser()。它是安全功能,但存储库应仅负责获取数据。

最好将调用Membership.GetUser()一级调高到MyController并将存储库API更新为

public IEnumerable<CustomModel> GetAllTodoItems(int userId)

它将帮助您在Repository上单独编写单元测试。

作为能够在MyController上编写测试的第二步,您可以将Membership.GetUser()依赖项移动到单独的服务(如SecurityService),并将其作为接口注入MyController。在单元测试中,您将使用假冒或模拟SecurityService初始化MyController