在MVC4中模拟User.Identity.Name

时间:2012-11-09 16:31:13

标签: c# asp.net-mvc unit-testing moq

我正在尝试为控制器(MVC4)中的一个方法编写测试。我用Moq。在测试方法中,我为我的存储库创建了一个模拟器,如下所示:

Mock<ISurveyRepository> mock = new Mock<ISurveyRepository>();

继续模拟存储库调用。其中第一个是:

int userId = repository.GetUserId(User.Identity.Name);

所以我将它添加到我的测试方法中:

mock.Setup(y => y.GetUserId("testName")).Returns(1);

不幸的是,这行代码给了我:

System.NullReferenceException: Object reference not set to an instance of an object.

如果我从控制器中删除上面的行并使用静态值(int userId = 1),则测试完成。

谁能告诉我为什么?

2 个答案:

答案 0 :(得分:1)

这可能无法解决您的moq问题,但对于它的价值,MvcContrib Test Helper对于模拟已登录的用户非常有用。

使用Test Helper,您可以编写如下代码:

FakeIdentity FakeId = new FakeIdentity(UserName);
FakeUser = new FakePrincipal(FakeId, new[] {  "Admin" });   
Thread.CurrentPrincipal = FakeUser;

模仿用户。希望这会有所帮助。

答案 1 :(得分:0)

获取用户名时,您的代码会抛出异常。 User返回当前HTTP请求的安全信息。在测试期间,您没有HTTP请求,因此此代码会抛出异常。

以下是此属性的实现:

public IPrincipal User
{
    get
    {
        if (HttpContext != null)            
            return HttpContext.User;

        return null;
    }
}

因此,如您所见,没有HttpContext,它返回null。因此,您需要设置HttpContext并为您的测试提供模拟IPrincipal。请参阅here如何创建假HttpContext。