我正在尝试为控制器(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),则测试完成。
谁能告诉我为什么?
答案 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。