Rhino Mocks异常,“貌似正常的代码中预期的#1,实际的#0”

问题描述 投票:0回答:1

我从一本关于MVVM的旧书中获得了一段代码,该代码可以正常工作,但是使用Rhino Mocks进行的测试失败,并显示以下消息:

测试方法TestProject.UnitTest1.UpdateCustomer_Always_CallsUpdateWithCustomer抛出异常: Rhino.Mocks.Exceptions.ExpectationViolationException:DataProvider.DoSomething(ConsoleApp.Customer);预期#1,实际#0

我提供一个我认为是等效的示例:

namespace ConsoleApp {
    class Program { static void Main () { } }

    public class Customer { public string ID { get; set; } }

    public class DataProvider {
        public virtual Customer GetCustomer (string id) => new Customer ();
        public virtual void DoSomething (Customer customer) { }
    }

    public class ViewModel {
        DataProvider _dataProvider;
        Customer _customer;

        public ViewModel (DataProvider dataProvider, string id) {
            _dataProvider = dataProvider;
            _customer = new Customer { ID = id };
        }

        public void DoSomething () => _dataProvider.DoSomething (_customer);
    }
}

和失败的测试

namespace TestProject {
    [TestClass]
    public class UnitTest1 {
        [TestMethod]
        public void UpdateCustomer_Always_CallsUpdateWithCustomer () {
            DataProvider dataProviderMock = MockRepository.GenerateMock<DataProvider> ();
            Customer expectedCustomer = new Customer ();
            dataProviderMock.Stub (u => u.GetCustomer (Arg<string>.Is.Anything)).Return (expectedCustomer);
            ViewModel target = new ViewModel (dataProviderMock, string.Empty);
            target.DoSomething ();
            dataProviderMock.AssertWasCalled (d => d.DoSomething (expectedCustomer));
        }
    }
}

我阅读了有关此结果的几篇文章,例如12,但这对我没有帮助。我读了this answer,这似乎很有趣:

当使用对象参数调用存根方法时,通常会出现此错误 我在测试和测试代码中构建的对象是在调用该方法之前构建的。

虽然这可能是Rhino Mocks失败的原因,但似乎是一个错误。

我的问题是:我的测试是否有问题,Rhino Mocks中存在错误,或者我的代码是否有问题?

c# rhino-mocks
1个回答
0
投票

示例视图模型不调用DataProvider.GetCustomer

它使用在构造函数中初始化的那个。

//...

_customer = new Customer { ID = id };

//...

因此,在给出的示例中,测试抛出的异常是准确的。

为了使测试根据其排列方式表现出预期的效果,实际上应该重构视图模型以与初始化Customer脱钩

public class ViewModel {
    DataProvider _dataProvider;
    string id;

    public ViewModel (DataProvider dataProvider, string id) {
        _dataProvider = dataProvider;
        this.id = id;
    }

    public void DoSomething () {
        Customer customer = _dataProvider.GetCustomer(id);
        _dataProvider.DoSomething (_customer);
    }
}

测试还应该更明确地说明要测试的内容

[TestClass]
public class UnitTest1 {
    [TestMethod]
    public void UpdateCustomer_Always_CallsUpdateWithCustomer () {
        //Arrange
        DataProvider dataProviderMock = MockRepository.GenerateMock<DataProvider> ();
        string id = "FakeId";
        Customer expectedCustomer = new Customer { Id = id };
        dataProviderMock.Stub (u => u.GetCustomer (id))
            .Return (expectedCustomer);
        ViewModel target = new ViewModel (dataProviderMock, id);

        //Act
        target.DoSomething ();

        //Assert
        dataProviderMock.AssertWasCalled (d => d.DoSomething (expectedCustomer));
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.