我正在为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的对象上调用方法。
问题是......是什么原因导致该对象变为空?
另一个问题是......也许有更好的方法可以做到这一点,如果是这样,我肯定会很高兴听到一个建议。
谢谢
答案 0 :(得分:1)
它不起作用。你试图创建模拟模拟的模拟......
如果您的控制器仅依赖于IModelObject,则只创建Mock并设置它的属性/方法以返回控制器中所需的内容。
如果没有IModelObject的代码,以及它在控制器中的使用方式,很难提供更好的示例。