0

我想问在下一个示例中如何使用 rhino 模拟:

   Public Class CustomerService 
    {
      Public void Register()
     {
         Action1();
         Action2();
     }

    private action1 ()
     {
       //this is a call to other dll.
       var isExist = _dataComponentService.CheckIfUserExist(userName);
     } 
   private action2()
     {
       //do some more work...
       // Call to dataComponentService. write some data in the database....
     }
    }

这只是我需要更新的真实代码的一个示例。当前的单元测试正在对数据库服务进行真正的调用。我想编写一个单元测试来检查公共 Register() 中的行为,而无需真正调用数据库服务。

是否可以模拟对位于私有方法中的其他组件的调用,而无需重新编写漏洞服务?

谢谢你先进

奥里

4

2 回答 2

3

你需要做一些依赖注入来让你的模拟进入你的测试类(有关 DI 的更多信息,请查看Martin Fowler 的这篇文章)。首先,您的“dataComponentService”类需要实现一个接口:

public interface IDataComponentService
{
    boolean CheckIfUserExist(String user);
}

然后,您可以通过添加适当的构造函数将实现该接口的类注入到 CustomerService 类中:

public class CustomerService 
{
    private IDataComponentService _dataComponentService

    // This constructor allows you to inject your dependency into the class
    public CustomerService(IDataComponentService dataComponentService)
    {
        _dataComponentService = dataComponentService;
    }

    Public void Register()
    {
        Action1();
        Action2();
    }

    private action1 ()
    {
        //this is a call to other dll.
        var isExist = _dataComponentService.CheckIfUserExist(userName);
    } 

    private action2()
    {
       //do some more work...
       // Call to dataComponentService. write some data in the database....
    }
}

现在,在您的测试代码中,您可以创建一个 IDataComponentService 的模拟...

var dataComponentServiceMock = MockRepository.GenerateMock<IDataComponentService>(); 
//add mock's behavior here...

...并因此将其传递给您的测试类...

var objUt = new CustomerService(dataComponentServiceMock);
objUt.Register();
// check method calls to the mock here...
于 2013-06-11T19:07:45.300 回答
2

你的问题引起了我的一些怀疑。一:如果执行数据库访问,则单元测试不是单元测试。如果它正在执行数据库访问,它更像是一个集成测试。二:您应该更多地依赖依赖注入并开始针对接口而不是对象进行编程。这意味着您注入必须为 _datacomponentservice 定义的接口

最重要的是。即使你有一个私有方法。您可以放松它以保护它并使其虚拟化。如果它是虚拟的,您可以制作一个特殊的测试版本,您可以在其中以不同的方式实现受保护的成员。

许多人定义了许多私有方法,但我发现有时这会阻碍未来的发展,我宁愿让它们受到保护而不是私有。因为你永远不知道未来会怎样。例如,我使用 .NET 反射器来浏览微软的代码,比如一个组合框,希望让它更灵活。有时我会花很多时间来做这件事,因为有些方法和类甚至在派生类中是不可访问的。

于 2013-06-11T19:08:16.760 回答