【发布时间】:2016-10-24 10:44:09
【问题描述】:
public class MyUser: IIdentity, IMyUser{
// ommited for abbrev.
}
public interface IMyUser
{
int Id { get; set; }
int? CompanyId { get; set; }
}
在 MyController 中,除了其他人之外,我还使用 MyUser 来填充 组合框
public ActionResult Details(int? subsidId = null, int? req = null)
{
...
MyUser user = this.User.GetInfo();
var obj1 = ... // ommited on purpose for abbrev.
populateCombos(subsidId, user.CompanyId, req);
}
我在 populateCombos 这一行遇到异常,因为用户对象始终为空。 在同一个控制器中,我正在注入 IMyUser 实现的接口
[Inject]
public IMyUser MyUser { get; set; }
此属性已使用 ninject 正确绑定(与我应用中的其他属性一样)
kernel.Bind<IMyUser>().To<MyUser>().InRequestScope();
现在在测试项目中,我正在使用模拟请求的依赖项初始化控制器
[SetUp]
public void Setup()
{
_controller = new MyController(){
... repositories....
MyUser = MockMyUser()
}
}
private IMyUser MockMyUser()
{
var u = new Mock<IMyUser>();
u.SetupGet(x => x.Id).Returns(1);
u.SetupGet(x => x.CompanyId).Returns(99);
return u.Object;
}
在测试方法里面我写了简单的测试
[Test]
public void CanDoDetails()
{
ViewResult res = this.controller.Details(1, 2) as ViewResult;
var model = result.Model as MyModel;
Assert.IsNotNull(model);
}
问题是:
为什么我会得到这种依赖(
MyUser内MyController为null) 导致它被正确注入?我做错了什么?
更新:
public static MyUser GetInfo(this IPrincipal principal)
{
if (principal != null)
{
return principal.Identity as MyUser;
}
return null;
}
更新 2: 根据下面的 Nkosi 回答,我进行了以下更改
public interface IMyUser : IIdentity { ... }
和内部细节ActionMethod控制器
IMyUser user = this.User.GetInfo();
在测试方法下
[SetUp]
public void Setup()
{
var mockUser = MockMyUser();
string[] roles = new[] { "Admin", "SuperUser" };
_controller = new MyController()
{
....
MyUser = this.MockMyUser(),
ControllerContext = new ControllerContext() {
Controller = _controller,
RequestContext = new RequestContext(new MockHttpContext(mockUser, roles), new RouteData())
}
}
}
but I'm still getting `IMyUser user = this.User.GetInfo();` `this.User` is still null.
附言我还将 GetInfo 更改为返回 IMyUser 而不是 MyUser。
【问题讨论】:
-
this.User是与控制器关联的Principal,假设GetInfo()是一个扩展方法,基于该principal创建你的MyUser? -
是的,恩科西,没错。
-
对
this.User.GetInfo()的调用通过返回一个空对象导致了问题。听起来GetInfo也需要被模拟出来。 -
我用 GetInfo 方法更新了这个问题。基本上这个方法只在测试环境下返回null,在应用上就可以了。
-
它返回 null,然后您尝试调用 null
MyUser对象上的CompanyId属性。您将不得不对返回的空引用做一些事情。你可以创建更多的模拟对象,重构你的代码,或者伪造CompanyId。这取决于您要测试的内容。
标签: c# asp.net-mvc unit-testing nunit moq