分配给控制器后,moq对象变为null

时间:2015-02-26 04:08:37

标签: c# tdd moq asp.net-mvc-5.2

我正在为MVC5控制器方法构建测试。我正在使用moq进行测试。我感兴趣的是如何测试需要身份验证的控制器方法,并使用userid值而不是用户名值来决定向浏览器/客户端显示哪些数据。

根据我目前研究的内容,有相当数量的代码可用于moq用户名,但用户ID值的代码不多(在我的情况下看起来像Guid)。我正在使用ASP.Net Identity作为帐户管理。我还为谷歌和Facebook登录添加了OWIN。

我正在使用依赖注入(使用Unity),因为它似乎是完成测试的唯一方法,而DI允许使用moq。

以下是从控制器方法中查找“NotNull”返回的测试方法示例:

Mock<ModelObject> CreateModelObjectFromHelper()
{
    var ci = new Mock<ClaimsIdentity>();
    var myHelper = new Mock<MyHelper>();
    myHelper.Setup(x => x.GetCurrentUserId(ci.Object)).Returns("333c188b-b33a-4233-83bd-5ea3a3333333");
    return new Mock<ModelObject>(myHelper.Object);
}


[TestMethod]
public async Task ExampleController_Method_NotNull()
{
    Mock<ModelObject> o = CreateModelObjectFromHelper();
    ExampleController controller = new ExampleController(o.Object as IModelObject);
    ViewResult result = await controller.MethodName() as ViewResult;
    //check for non null result
    Assert.IsNotNull(result);
}

GetCurrentUserId方法是使用以下代码查询userid的User.Identity对象的地方:

var userIdClaim = user.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier);
userIdValue = userIdClaim.Value.ToString();

该方法据说被moq取代。 GetCurrentUserId方法是辅助类(MyHelper)中的虚方法,它是模型对象(ModelObject)的构造函数的参数,它是控制器(ExampleController)的构造函数的参数。

调试器(Visual Studio 2013)中测试方法的作用是在CreateModelObjectFromHelper方法中创建对象,但是在行创建ExampleController时:

ExampleController controller = new ExampleController(o.Object as IModelObject);

MyHelper moq'd对象变为null。我可以看到该对象在此语句之前有一个值,但在此语句中,MyHelper对象变为null ...并且整个测试失败。我认为它失败了,因为很难在一个null的对象上调用方法。

问题是......是什么原因导致该对象变为空?

另一个问题是......也许有更好的方法可以做到这一点,如果是这样,我肯定会很高兴听到一个建议。

谢谢

1 个答案:

答案 0 :(得分:1)

它不起作用。你试图创建模拟模拟的模拟......

如果您的控制器仅依赖于IModelObject,则只创建Mock并设置它的属性/方法以返回控制器中所需的内容。

如果没有IModelObject的代码,以及它在控制器中的使用方式,很难提供更好的示例。