【问题标题】:Why do I get an ExpectationViolationException when using a Stub?为什么在使用 Stub 时会收到 ExpectationViolationException?
【发布时间】:2011-01-25 14:33:10
【问题描述】:

此测试使用 NUnit 2.5 和 Rhino.Mocks 3.5:

[TestFixture]
public class ExcelWorksheetColumnTests
{
        private const string _name = "F1";
        private const int _index = 0;

        private MockRepository _repo;


        [SetUp]
        public void SetUp(){_repo = new MockRepository();}


        private ExcelWorksheetColumn CreateColumnUsingFixtureFieldsButWith(IExcelWorksheet excelWorksheet)
        {
            return new ExcelWorksheetColumn(_name, _index, excelWorksheet);
        }

        [Test]
        public void When_SelectedShootColumnType_Is_Changed_Raises_SelectedShootColumnTypeChanged_Event()
        {
            var stubWorksheet = _repo.Stub<IExcelWorksheet>();

            ExcelWorksheetColumn column =
                CreateColumnUsingFixtureFieldsButWith(stubWorksheet);

            stubWorksheet
               .Stub(p => p.GetSelectedShootColumnType(column))
               .Return(ShootColumnType.Generic);

            _repo.ReplayAll();

            bool itHappened = false;

            column.SelectedShootColumnTypeChanged 
                += (s, e) => { itHappened = true; };

            column.SelectedShootColumnType = ShootColumnType.SubjectId;

            Assert.That(itHappened);
        }

        [TearDown]
        public void TearDown()
        {
            _repo.ReplayAll();
            _repo.VerifyAll();
        }
}

失败并显示此消息:

Rhino.Mocks.Exceptions.ExpectationViolationException : IExcelWorksheet.SetSelectedShootColumnType( ClassPhotolink.Model.CreateSubjectList.ExcelWorksheetColumn, SubjectId);

预期 #0,实际 #1。

我认为存根用于返回值或忽略方法调用。为什么它试图验证调用

IExcelWorksheet.SetSelectedShootColumnType(
    IExcelWorksheetColumn column, 
    ShootColumnType type)

?

在 rhino mocks wiki 中,它说关于 Stub 扩展方法“请记住,默认情况下 Rhino Mocks 将忽略意外的方法调用。


测试编辑。

删除 SetUp & TearDown 代码,仍然失败:

    [Test]
    public void When_SelectedShootColumnType_Is_Changed_Raises_SelectedShootColumnTypeChanged_Event()
    {
        var repo = new MockRepository();
        var stubWorksheet = repo.Stub<IExcelWorksheet>();

        ExcelWorksheetColumn column = CreateColumnUsingFixtureFieldsButWith(stubWorksheet);

        stubWorksheet
            .Stub(p => p.GetSelectedShootColumnType(column))
            .Return(ShootColumnType.Generic);

        repo.ReplayAll();

        bool itHappened = false;

        column.SelectedShootColumnTypeChanged += (s, e) => { itHappened = true; };

        column.SelectedShootColumnType = ShootColumnType.SubjectId;

        Assert.That(itHappened);
    }

但这如我所愿。

    [Test]
    public void When_SelectedShootColumnType_Is_Changed_Raises_SelectedShootColumnTypeChanged_Event()
    {
        var stubWorksheet = MockRepository.GenerateStub<IExcelWorksheet>();

        ExcelWorksheetColumn column = CreateColumnUsingFixtureFieldsButWith(stubWorksheet);

        stubWorksheet
            .Stub(p => p.GetSelectedShootColumnType(column))
            .Return(ShootColumnType.Generic);

        bool itHappened = false;

        column.SelectedShootColumnTypeChanged += (s, e) => { itHappened = true; };

        column.SelectedShootColumnType = ShootColumnType.SubjectId;

        Assert.That(itHappened);
    }

所以它似乎与 repo.Stub() 与 MockRepository.GenerateStub() 有关系;

【问题讨论】:

    标签: c# rhino-mocks


    【解决方案1】:

    使用Stub() 意味着您确实期待方法调用。 意外调用是对未设置期望的方法的调用。

    更新

    我现在想知道问题是否在于您使用不必要的设置、拆卸和记录/重放。

    如果你这样写测试会发生什么:

    [TestFixture]
    public class ExcelWorksheetColumnTests
    {
            private const string _name = "F1";
            private const int _index = 0;
    
            private ExcelWorksheetColumn CreateColumnUsingFixtureFieldsButWith(IExcelWorksheet excelWorksheet)
            {
                return new ExcelWorksheetColumn(_name, _index, excelWorksheet);
            }
    
            [Test]
            public void When_SelectedShootColumnType_Is_Changed_Raises_SelectedShootColumnTypeChanged_Event()
            {
                var stubWorksheet = MockRepository.Stub<IExcelWorksheet>();
    
                ExcelWorksheetColumn column =
                    CreateColumnUsingFixtureFieldsButWith(stubWorksheet);
    
                stubWorksheet
                   .Stub(p => p.GetSelectedShootColumnType(column))
                   .Return(ShootColumnType.Generic);
    
                bool itHappened = false;
    
                column.SelectedShootColumnTypeChanged 
                    += (s, e) => { itHappened = true; };
    
                column.SelectedShootColumnType = ShootColumnType.SubjectId;
    
                Assert.That(itHappened);
            }
    }
    

    【讨论】:

    • 为了澄清,我在 IExcelWorksheetColumn.GetSelectedShootColumnType(column) 上存根了所需的返回值。我没有对 IExcelWorksheetColumn.SetSelectedShootColumnType(column,value) 设置期望,这是它所抱怨的方法,因为它是无效的,我希望它会作为意外调用而被忽略。
    • 是的,我让它像你建议的那样使用静态 GenerateStub() 方法工作,谢谢。我将不得不研究令人困惑的 Rhino-Mocks 文档的各种来源的差异。
    猜你喜欢
    • 2017-12-21
    • 2022-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多