1

前言:我正在测试一项服务。每隔 n 秒,它就会启动一些进程并运行一些作业。我想通过集成测试覆盖此服务的顶层(从 ServiceBase 继承的类)。我的目标是验证:1. 我可以启动它,2. 它设置所有计时器,以及 3. 创建作业管理对象来执行作业(至少在计时器上看到一次执行)。将来我们希望通过将不同的作业移动到不同的线程来提高性能,这也会增加代码的复杂性。(这是现在测试它的另一个原因,虽然它仍然很简单)

问题本身:我应该如何测试服务?此类中的所有方法和属性都是受保护的或私有的。而对于 RhinoMocks,我只能存根公共成员。

更多想法:这个类中有一个私有成员 AppJobManagement,我想存根。我不想使用这个类的真实实例,因为它连接到数据库并且在运行时可能会做很多不需要的更改。我可以将其公开以进行存根。

但是我遇到的下一个问题是如何断言服务类可以正常工作?我将需要再次公开测试中的方法。这是我想避免的。

任何建议都非常感谢!

4

1 回答 1

2

您可以创建一个公共或内部构造函数来依赖AppJobManagement. 如果可以,请更改对此类接口的引用,因为它可能使测试更容易。

public class ServiceToBeTested : ServiceBase
{
    private IAppJobManagement _appJobManagment;

    public ServiceToBeTested()
    {
        _appJobManagment = new AppJobManagement();
    }

    internal ServiceToBeTested(IAppJobManagement appJobManagment)
    {
        _appJobManagment = appJobManagment;
    }
}

如果ServiceToBeTested你想模拟/伪造许多受保护的方法,你应该考虑另一个依赖项。例如,而不是:

public void DoSomethingImportant(string foo)
{
    if (someCondition)
    {
        DoThisOneWay(foo);
    }
    else
    {
        DoThisDifferently(foo);
    }
}

protected void DoThisOneWay(string foo) {}
protected void DoThisDifferently(string foo) {}

您可以使用另一个对象:

public interface IServiceWorker
{
    void DoThisOneWay(string foo);
    void DoThisDifferently(string foo);
}

public void DoSomethingImportant(string foo)
{
    if (someCondition)
    {
        _worker.DoThisOneWay(foo);
    }
    else
    {
        _worker.DoThisDifferently(foo);
    }
}

IServiceWorker _worker很容易被嘲笑。

更新

另一种模式是使用Factory类来生成这些对象。

public interface IAppJobManagementFactory
{
    IAppJobManagement Create(string arg1, int arg2);
}

这也可以嘲笑。

于 2013-09-11T09:56:49.197 回答