无法验证方法调用 - Rhino mock

时间:2014-05-12 11:43:53

标签: c# unit-testing rhino-mocks

我收到一个例外:"对象引用没有设置为对象的实例"。

我正在尝试评估是否执行了Location和Manufacturing类方法ResetAllProperties()。

我做错了什么?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using Rhino.Mocks;

namespace Test
{
    public class Engine
    {
        public Engine() { }

        public EngineStatus Status { get; internal set; }
        public virtual EngineLocation Location { get; set; }
        public virtual EngineManufacturing Manufacturing { get; set; }
    }

    public abstract class EngineStatus
    {
        protected readonly Engine engine = null;

        public EngineStatus(Engine engine)
        {
            this.engine = engine;
        }

        public abstract void ResetAllProperties();
    }

    public class FirstEngineStatus : EngineStatus
    {
        public FirstEngineStatus(Engine engine) : base(engine) { }

        public override void ResetAllProperties()
        {
            this.engine.Location.ResetAllProperties();
            this.engine.Manufacturing.ResetAllProperties();
        }
    }

    public class EngineLocation
    {
        public string CustomerName { get; set; }

        public virtual EngineManufacturing Manufacturing { get; set; }
        public virtual Engine Engine { get; set; }

        public void ResetAllProperties()
        {
            this.CustomerName = null;
        }
    }

    public class EngineManufacturing
    {
        public Nullable<DateTime> EntryDate { get; set; }

        public virtual EngineLocation Location { get; set; }
        public virtual Engine Engine { get; set; }

        public void ResetAllProperties()
        {
            this.EntryDate = null;
        }
    }

    [TestClass]
    public class Test
    {
        [TestMethod]
        public void ResetAllProperties_AssertWasCalled()
        {
            // Arrange
            var engine = MockRepository.GenerateMock<Engine>();
            var status = MockRepository.GeneratePartialMock<FirstEngineStatus>(engine);

            engine.Stub(action => action.Location.ResetAllProperties());
            engine.Stub(action => action.Manufacturing.ResetAllProperties());

            // Act
            status.ResetAllProperties();

            // Assert
            engine.AssertWasCalled(action => action.Location.ResetAllProperties());
            engine.AssertWasCalled(action => action.Manufacturing.ResetAllProperties());
        }
    }
}

1 个答案:

答案 0 :(得分:0)

您声明LocationManufacturing的行为,因此这些是应该被模拟的对象。此外,在检查发生了什么事情时,请使用Expects而不是Stub。其他一切都应该是具体的。如果您将ResetAllProperties方法设为虚拟,则以下方法有效:

[TestMethod]
public void ResetAllProperties_AssertWasCalled()
{
    var location = MockRepository.GeneratePartialMock<EngineLocation>();
    var manufacturing = MockRepository.GeneratePartialMock<EngineManufacturing>();

    // Arrange
    var engine = new Engine
    {
        Location = location,
        Manufacturing = manufacturing
    };
    var status = new FirstEngineStatus(engine);
    location.Expect(action => action.ResetAllProperties());
    manufacturing.Expect(action => action.ResetAllProperties());

    // Act
    status.ResetAllProperties();

    // Assert
    location.VerifyAllExpectations();
    manufacturing.VerifyAllExpectations();
}

但是,这似乎是在测试实现而不是功能。你真的想测试什么?在我看来,您希望测试CustomerNameEntryDate是否设置为null。您可以在不使用任何模拟的情况下对此进行测试,如下所示:

[TestMethod]
public void ResetAllProperties_AssertWasCalled()
{
    // Arrange
    var engine = new Engine
    {
        Location = new EngineLocation { CustomerName = "Dzenan" },
        Manufacturing = new EngineManufacturing { EntryDate = DateTime.Today }
    };
    var status = new FirstEngineStatus(engine);

    // Act
    status.ResetAllProperties();

    // Assert
    Assert.IsNull(engine.Location.CustomerName);
    Assert.IsNull(engine.Manufacturing.EntryDate);
}