我有一个使用内部代理类来调用提供数据的服务的类。当然,如果该方法在内部创建代理,则测试该类存在问题。你认为代理应该在构造函数中给出,即使它可以在没有“知道”的情况下在里面创建吗?
答案 0 :(得分:1)
您应该通过依赖注入(构造函数,属性,参数)为类提供类依赖性。这使您的类可测试并允许模拟所有这些依赖项。
更新: 注入服务代理:
class Foo
{
private IServiceProxy _serviceProxy;
public Foo(IServiceProxy _serviceProxy)
{
_serviceProxy = serviceProxy;
}
public void Bar()
{
var staff = _serviceProxy.GetStaff();
}
}
顺便说一句,请考虑隐藏有关您班级代理的信息。例如。通过代理实现与实际服务相同的接口,并为您的类提供IService。
UPDATE2(网关):
我们所有的域名需求 - 获得一些员工。所以,我们定义接口:
interface IStaffService
{
Staff GetStaff();
}
我们的域类(您的测试类仅使用此接口,不依赖于Web服务,代理创建和其他基础结构问题)。
接下来为您的服务创建网关(请参阅Martin Fowler网站上的定义):
public MyServiceProxyGateway : IStaffService
{
public Staff GetStaff()
{
var proxy = new YourProxyType();
proxy.X = value;
proxy.Y = value;
var response = proxy.CallActualServiceMethod();
Staff staff = new Staff();
staff.Value = response.Something;
return staff;
}
}
您的代码现在完全没有意识到所有这些基础架构通信。并且您使用方便的界面GetStaff而不是CallActualServiceMethod。
答案 1 :(得分:1)
嗯,“代理类知道如何实例化自己”和“类知道如何实例化代理类”之间存在差异。如果你把这些知识打包在内,那么第二个使单元测试变得更难(如果不是不可能的话)。
我使用依赖注入(通过框架,构造函数或属性)将这些知识带给调用者 - 并使其可测试。
答案 2 :(得分:1)
为了测试我的代理类,我通常会给出应该在构造函数中代理的目标。 Thous让我有可能给出一个存根对象进行测试。
public class MyProxy : IProxiedInterface
{
private IProxiedInterface _Target;
public MyProxy(IProxiedInterface target)
{
if(target == null)
throw new ArgumentNullException("target");
_Target = target;
}
// ToDo: Implement all functions from IProxiedInterface
// and delegate them to the target
public bool DoSomething()
{
return _Target.DoSomething();
}
}