0

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

从我到目前为止的研究来看,有大量代码可用于 moq 用户名,但用户 ID 值的代码不多(在我的情况下,它看起来像一个 Guid)。我使用 ASP.Net Identity 作为帐户管理。我还为 Google 和 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 方法是我使用以下代码在 User.Identity 对象中查询用户 ID 的地方:

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

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

测试方法的调试器(Visual Studio 2013)中发生的情况是对象是在 CreateModelObjectFromHelper 方法中创建的,但是在以下行创建 ExampleController 时:

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

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

问题是......是什么导致这个对象变为空?

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

谢谢

4

1 回答 1

1

它不是那样工作的。您尝试创建模拟模拟的模拟...

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

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

于 2015-02-28T04:18:38.497 回答