2009-09-23 66 views
0

我有以下代码(简化)。如何在Rhino模拟AAA中模拟其他课程的方法调用?

public class OrderProcessor 
{ 
    public virtual string PlaceOrder(string test) 
    { 
     OrderParser orderParser = new OrderParser(); 
     string tester = orderParser.ParseOrder(test); 
     return tester + " here" ; 
    } 

} 

public class OrderParser 
{ 

    public virtual string ParseOrder(string test) 
    { 
     if (!string.IsNullOrEmpty(test.Trim())) 
     { 
      if (test == "Test1") 
       return "Test1"; 
      else 
      { 
       return "Hello"; 
      } 
     } 
     else 
      return null; 
    } 
} 

我的测试是如下 -

public class OrderTest 
    { 
     public void TestParser() 
     { 
     // Arrange 

     var client = MockRepository.GenerateMock<OrderProcessor>(); 
     var spec = MockRepository.GenerateStub<OrderParser>(); 

     spec.Stub(x => x.ParseOrder("test")).IgnoreArguments().Return("Test1"); 

     //How to pass spec to client so that it uses the same. 

     } 
    } 

现在怎么办我测试客户端,以便它使用从OrderParser嘲笑的方法。 我可以模拟OrderParser,但我如何将它传递给orderProcessor模拟类?

请让我知道。

在此先感谢。

回答

1

我对你的测试有点困惑,因为除了RhinoMocks的工作原理外,你没有真正测试任何东西。你创建两个嘲笑,然后对它们做一些断言。你甚至没有测试过你的真实课程。

如果你真的想要得到一个好的单元测试,你需要做一些依赖注入。您可以快速重构代码以使用接口和依赖注入来使您的测试有效。

开始从你的OrderParser类中提取出的接口:

public interface IOrderParser 
{ 
    String ParseOrder(String value); 
} 

现在确保您的OrderParser类实现该接口:

public class OrderParser: IOrderParser{ ... } 

现在,您可以重构你的订单处理器类采取一个实例通过其构造函数的IOrderParser对象。通过这种方式,您可以将依赖关系“注入”到类中。

public class OrderProcessor 
{ 
    IOrderParser _orderParser; 

    public OrderProcessor(IOrderParser orderParser) 
    { 
     _orderParser = orderParser; 
    } 

    public virtual string PlaceOrder(string val) 
    { 
     string tester = _orderParser.ParseOrder(val); 
     return tester + " here" ; 
    } 
} 

在您的测试中,您只想嘲笑依赖项而不是SUT(Subject under Test)。您的测试将是这个样子:

public class OrderTest 
    { 
     public void TestParser() 
     { 
     // Arrange 

     var spec = MockRepository.GenerateMock<IOrderParser>(); 
     var client = new OrderProcessor(spec); 

     spec.Stub(x => x.ParseOrder("test")).IgnoreArguments().Return("Test1"); 

     //Act 
     var s = client.PlaceOrder("Blah"); 

     //Assert 
     Assert.AreEqual("Test1 Here", s); 

     } 
    } 

这是我很难衡量你正在尝试用你的类的事,但你应该能够从该明白了吧。几个公理遵循:

  1. 使用过度继承接口和组成
  2. 使用dependency injection对于外部依赖性(控制反转)
  3. 测试单个单元,和模拟其依赖
  4. 只有嘲笑一个水平的依赖关系。如果您正在测试类X依赖于Y,它取决于Z,你应该只被嘲笑Y和Z.从未
  5. 始终test behavior,从来没有实施细则

你似乎是在正确的轨道上,但需要一点指导。我建议阅读材料Martin Fowler,和Bob Martin必须加快速度。