我有一个服务类,它在执行操作之前创建一个新的具体PropertyClass。我正在尝试测试是否运行了DoSomething()。 是否可以创建stud并将返回的Property值控制为模拟对象?
public class ServiceClass
{
public PropertyClass Property {set; get;}
public void Action()
{
Property = new PropertyClass();
Property.DoSomething();
}
}
[Test] // This test does not work.
public class Action_Test
{
var service = new ServiceClass();
var mockPropertyClass = MockRepository.GenerateMock<IPropertyClass>();
service.Property.Stub(x=> new PropertyClass()).Return(mockPropertyClass);
service.Action();
service.Property.AssertWasCalled(x => x.DoSomething());
}
答案 0 :(得分:1)
您的Action方法正在创建自己的PropertyClass实例,它会覆盖您的存根。
public void Action()
{
if (Property == null)
Property = new PropertyClass();
Property.DoSomething();
}
每次使用Property属性时必须检查的一个很好的方法是在构造函数中分配属性。
public ServiceClass() {
Property = new PropertyClass();
}
然后Action方法就是:
public void Action()
{
Property.DoSomething();
}
答案 1 :(得分:1)
没有。但您可以使用factory design pattern轻松缓解此问题。考虑:
public class ServiceClass
{
private readonly IPropertyClassFactory factory;
public PropertyClass Property { get; private set; }
public ServiceClass(IPropertyClassFactory factory)
{
this.factory = factory;
}
public void Action()
{
Property = factory.CreateInstance();
Property.DoSomething();
}
}
在测试中,您创建模拟工厂,该工厂返回模拟对象。像这样:
[Test]
public class Action_Test
{
var factoryMock = MockRepository.GenerateMock<IPropertyClassFactory>();
var propertyMock = MockRepository.GenerateMock<IPropertyClass>();
factoryMock.Stub(f => f.CreateInstance()).Returns(propertyMock);
var service = new ServiceClass(factoryMock);
service.Action();
propertyMock.AssertWasCalled(x => x.DoSomething());
}
请注意,当工厂这个简单的时,您也可以使用Func<IPropertyClass>
而不是创建额外的类/接口对。