【问题标题】:How do I resolve my dependencies for testing?如何解决我的测试依赖项?
【发布时间】:2013-08-15 04:15:43
【问题描述】:

我的控制器有依赖项,我正在使用 Castle Windsor 通过依赖项注入来解决这些依赖项。

这很好用,甚至允许我用“模拟”依赖项替换一些依赖项,以便我可以测试我的控制器。

但是,假设我有以下内容:

Public Class AccountController
    Inherits Controller

    Public Property SecurityService As ISecurityService

    Public Sub New(securityService As ISecurityService)
        Me.SecurityService = securityService
    End Sub

End Class

Public Class DefaultSecurityService
    Implements ISecurityService

    Public Property SomeDependency As ISomeClass

End Class

在这种情况下,我的 AccountController 依赖于 ISecurityService,而 ISecurityService 则依赖于另一类。我的情况更复杂,更抽象。我绝对无法直接向SecurityService 注入任何东西。

这让我觉得我的 DI 容器可以为我做这件事。我想让 Castle Windsor 在我运行测试(例如集成测试)时识别出来,并将任何服务替换为它找到的任何“模拟”服务。这意味着我可以定义一个名为 MockSomeClass 的模拟 ISomeClass,Castle Windsor 会自动注入该类而不是常规类。

如何实现?我能找到的关于这个主题的唯一信息是Auto-mocking ContainerMark Seemann。但它很复杂,我不确定它是否与我的需要有关。

(代码示例中可接受 VB.NET 和 C#)

【问题讨论】:

    标签: asp.net-mvc-4 dependency-injection castle-windsor integration-testing ioc-container


    【解决方案1】:

    鉴于您可以将接口注入控制器,这意味着默认安全服务的依赖项没有实际意义。

    只需使用您选择的模拟工具,例如 MOQ、RhinoMocks 等,然后将其中一个模拟工具提供给 accountcontroller。

    在最小起订量中,我会执行以下操作:

     var service = new Mock<ISecurityService>();
     service.setup(s= > s.SomeCall(It.IsAny<int>())).Returns(new List<OfSomething>());
    
     var controller = new AccountController(service.Object);
    
    
     controller.DoSomething(5); // call on service as check the result here
    
     service.Verify(m => m.SomeCall(It.Is<int>(i => i == 5)), Times.Once());
    

    使用这样的模拟工具,您无需担心依赖项的依赖关系,因为它不是您要测试的依赖项,而只是两者之间的交互。

    当你来测试 DefaultSecurityService 时,你需要担心它的依赖关系。

    HTH

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-18
      • 2012-01-03
      • 2014-04-14
      • 1970-01-01
      • 2020-11-03
      • 1970-01-01
      • 2021-06-24
      • 1970-01-01
      相关资源
      最近更新 更多