【问题标题】:Unit Testing error "Object reference not set to an instance of an object."单元测试错误“对象引用未设置为对象的实例。”
【发布时间】:2013-08-18 21:08:30
【问题描述】:

在我的控制器中,我想测试控制器是否正在调用存储库方法。 这是 controller

中的方法
[HttpGet]
public ActionResult GetModulePropertyName(string moduleTypeValue)
{
  var temp = _modulerepository.GetModuleKindPropertyNames(moduleTypeValue);

  IList<Property> model = temp
     .Select(item => new Property {Name = item})
     .ToList();

  return PartialView("GetModulePropertyName",model);
}

这里是测试方法

[TestMethod]
public void GetModulePropertyName_Action_Calls_GetModuleKindPropertyNames()
{
  _mockRepository.Stub(x => x.GetModuleKindPropertyNames(Arg<string>.Is.Anything));

  _controller.GetModulePropertyName(Arg<string>.Is.Anything);

  _mockRepository.AssertWasCalled(x=>x.GetModuleKindPropertyNames(Arg<string>.Is.Anything));
}

它抛出一个错误

Test method AdminPortal.Tests.ModuleControllerTests.GetModulePropertyName_Action_Calls_GetModuleKindPropertyNames threw exception: 
System.NullReferenceException: Object reference not set to an instance of an object.
    at System.Linq.Queryable.Select(IQueryable`1 source, Expression`1 selector)
   at AdminPortal.Areas.Hardware.Controllers.ModuleController.GetModulePropertyName(String moduleTypeValue) in ModuleController.cs: line 83
   at AdminPortal.Tests.ModuleControllerTests.GetModulePropertyName_Action_Calls_GetModuleKindPropertyNames() in ModuleControllerTests.cs: line 213

我使用 RhinoMock 作为模拟工具。 有人可以帮我解决我犯的错误吗?

【问题讨论】:

  • 下面有正确的答案,但我认为您的测试过于侵入性。由于您正在测试的方法具有返回值,因此编写测试返回的内容就足够了。只要你得到正确的结果,如何获得结果的细节就不需要测试了,这样的测试只会增加你的测试工具的维护和脆弱性。
  • 所以你想说检查控制器方法是否正在调用存储库以获取所需的数据并呈现正确类型的视图没有意义?
  • 我不这么认为。我会编写测试来检查返回的 PartialView 是否正确。除此之外,底层代码如何解决它并不重要。如果有很多逻辑需要在那里发生,请将其拆分为自己的模块并围绕该逻辑单独进行单元测试。如果没有其他要测试的输出,测试实际的方法调用是最后的手段。你想测试你的结果,而不是你的架构。 :)

标签: c# asp.net-mvc unit-testing asp.net-mvc-4 rhino-mocks


【解决方案1】:

在方法存根后使用Return 表示它应该返回什么,例如:

_mockRepository
  .Stub(x => x.GetModuleKindPropertyNames(Arg<string>.Is.Anything))
  .Return(Enumerable.Empty<string>().AsQueryable());

另外,更改这一行:

_controller.GetModulePropertyName(Arg<string>.Is.Anything);

到这里:

_controller.GetModulePropertyName(string.Empty);

正如例外所解释的 - Arg 仅用于模拟定义。

【讨论】:

    【解决方案2】:

    您的存根没有回报。

    _mockRepository.Stub(x => x.GetModuleKindPropertyNames(Arg<string>.Is.Anything));
    

    如果没有返回,这一行将针对空引用运行 lambda

     IList<Property> model = temp.Select(item => new Property {Name = item}).ToList();
    

    所以:

        _mockRepository.Stub(x => x.GetModuleKindPropertyNames(Arg<string>.Is.Anything)).Return(new Module[]{}); // set some return data here
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-09
      • 2012-08-31
      • 2011-11-21
      • 2012-10-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多