我一直在研究一个只能获取和返回字符串的COM对象的包装器。 COM对象的接口如下所示:

    interface IMapinfo
    {
        void Do(string cmd);
        string Eval(string cmd);
    }

现在我已经创建了包含基本函数的类:

    public class Table 
    {
        IMapinfo MI;
        public string Name
        {
            //pass the command to the COM object and get back the name.
            get{return MI.Eval("TableInfo(1,1")");}
        }

    }

现在我想对这些类进行单元测试,而不必每次都创建真正的COM对象,设置世界然后运行测试。所以我一直在研究使用模拟对象,但我对如何在这种情况下使用模拟有点困惑。

我打算使用Moq,所以我写了这样的测试:

        [Test]
        public void MockMapinfo()
        {
            Moq.Mock<Table> MockTable = new Moq.Mock<Table>();
            MockTable.ExpectGet(n => n.Name)
                .Returns("Water_Mains");

            Table table = MockTable.Object;
            var tablename = table.Name;

            Assert.AreEqual("Water_Mains", tablename,string.Format("tablename is {0}",tablename));
            Table d = new Table();
         }

这是模拟COM对象的正确方法吗?如何将字符串发送到eval函数是正确的?或者我做错了吗?

有帮助吗?

解决方案

这是重复的吗? 如何使用COM OLE对象进行TDD

编辑:看起来你问的是同一个问题,但要验证你的模拟代码(OOPS)。

你的嘲弄场景不太适合你。您想要隔离外部依赖项是正确的,并且您的COM对象肯定符合该标准。虽然我不是moq家伙(我更喜欢RhinoMocks),但模拟背后的想法是交互测试......

交互测试是关于一致的对象集合如何协同工作。此方案中的有效测试是为依赖于COM对象行为的组件编写测试。

在这种情况下,您的<!>“;表<!>”;它的作用类似于COM对象的包装,也取决于COM对象的行为。为了论证,假设您的Table对象针对从COM对象返回的值执行自定义逻辑。

现在,您可以使用Mocks 模拟您的COM对象的行为,为您的Table对象编写独立的测试。

public class Table
{
   public Table(IMapInfo map)
   {
      _map = map;
   }

   public string Name
   {
      get 
      {
        string value = _map.Eval("myexpression");
        if (String.IsNullOrEmpty(value))
        {
            value = "none";
        }
        return value;
      }
   }

   private IMapInfo _map;
}

[TestFixture]
public class TableFixture // is this a pun?
{
   [Test]
   public void CanHandleNullsFromCOM()
   {
       MockRepository mocks = new MockRepository(); // rhino mocks, btw
       IMapInfo map = mocks.CreateMock<IMapInfo>();

       using (mocks.Record())
       {
          Expect.Call(map.Eval("myexpression").Return(null);
       }

       using (mocks.PlayBack())
       {
          Table table = new Table(map);
          Assert.AreEqual("none", table.Name, "We didn't handle nulls correctly.");
       }

       mocks.verify();
   }
}

也许你的COM对象在被调用时抛出异常,或者它可能不能很好地处理字符串表达式。我们实际上正在测试我们的Table对象如何与IMapInfo交互而不依赖于COM对象的实现。我们还强制执行Table和IMapInfo之间的关系,因为在测试期间必须调用IMapInfo对象。

希望这有帮助。

scroll top