【问题标题】:Is it possible to create a stub for a creation of a concrete class?是否可以为创建具体类创建存根?
【发布时间】:2013-06-17 12:21:08
【问题描述】:

我有一个服务类,它在执行操作之前创建一个新的具体 PropertyClass。我正在尝试测试 DoSomething() 是否已运行。 是否可以创建螺柱并将返回的属性值控制为模拟对象?

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());
}

【问题讨论】:

    标签: c# unit-testing rhino-mocks


    【解决方案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();
        }
    }
    

    在测试中,您创建 mocked 工厂,它返回 mocked 对象。像这样:

    [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&lt;IPropertyClass&gt;,而不是创建额外的类/接口对。

    【讨论】:

    • 我也想过这种“工厂”的方式,因为工厂是“这么简单”,所以没有这样做。而且,我现在意识到,我只是想得不够远。我曾尝试使用 Func,它是成功的。非常感谢您的帮助!!!
    【解决方案2】:

    您的 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();
    }
    

    【讨论】:

    • 我认为可能是这种情况...谢谢您的回复。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多