Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在服务中存根和测试受保护的成员?_C#_.net_Unit Testing_Service_Rhino Mocks - Fatal编程技术网

C# 如何在服务中存根和测试受保护的成员?

C# 如何在服务中存根和测试受保护的成员?,c#,.net,unit-testing,service,rhino-mocks,C#,.net,Unit Testing,Service,Rhino Mocks,开场白:我正在测试一项服务。每n秒,它启动一些进程并运行一些作业。 我想通过集成测试来介绍此服务的顶层(从ServiceBase继承的类)。我的目标是验证:1。我可以开始,2。它设置所有计时器和3。创建作业管理对象以执行作业(至少查看计时器上的一次执行)。 将来,我们希望通过将不同的作业移动到不同的线程来提高性能,这也会增加代码的复杂性。(这是现在测试它的另一个原因,尽管它仍然很简单) 问题本身:我应该如何测试服务?此类中的所有方法和属性都是受保护的或私有的。而使用Rhinomock,我只能给公

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

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

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

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


非常感谢您的建议

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

public class ServiceToBeTested : ServiceBase
{
    private IAppJobManagement _appJobManagment;

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

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

如果<代码> Service TeBestEX/<代码>有许多您想模拟/伪造的受保护方法,那么您应该考虑另一种依赖关系。例如,而不是:

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工人很容易被嘲笑

更新

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

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

这也是可以模仿的。

谢谢你的想法,但不幸的是,我无法应用此解决方案,因为我在timer Essed事件中创建并销毁了此对象。@A看看为什么你不能在测试方法中创建用于测试的Instation of service?在实际代码中如何实例化此对象并不重要。