故事前:我正在测试服务。每隔n秒启动一些进程并运行一些作业。 我想通过集成测试覆盖此服务的顶级(从ServiceBase继承的类)。我的目标是验证:1。我可以启动它,2。它设置所有计时器; 3.创建作业管理对象以执行作业(至少在计时器上看到一次执行)。 在未来,我们希望通过将不同的作业移动到不同的线程来提高性能,这也会增加代码的复杂性。(这是现在测试它的另一个原因,虽然它仍然非常简单)
问题本身:我应该如何测试服务?此类中的所有方法和属性都是受保护的或私有的。使用RhinoMocks,我只能存储公共成员。
更多想法:这个类中有一个私有成员AppJobManagement,我想要存根。我不想使用这个类的真实实例,因为它连接到数据库并且在运行时可能会做很多不需要的更改。 我可以把它公之于众。
但是我的下一个问题是,我如何断言服务类是否正常工作?我需要再次公开测试下的方法。这就是我想避免的。
非常感谢任何建议!
答案 0 :(得分: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);
}
这也可以被嘲笑。