我一直在为只能获取和返回字符串的 COM 对象开发一个包装器。 COM 对象的接口(interface)如下所示:
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 函数的字符串是否正确?还是我做错了?
最佳答案
这是重复的吗? How would I do TDD with a COM OLE object
编辑:看起来您在问同样的问题,但为了验证您的模拟代码(OOPS)。
你还没有完全适应你的模拟场景。您想要隔离外部依赖关系是正确的,并且您的 COM 对象肯定满足该标准。虽然我不是一个最小起订量的人(我更喜欢 RhinoMocks),但模拟背后的想法是交互测试...
交互测试是关于内聚的对象集如何协同工作的。这种情况下的有效测试是为依赖于 COM 对象行为的组件编写测试。
在这种情况下,您的“表”就像 COM 对象的包装器一样,也依赖于 COM 对象的行为。为了便于论证,假设您的 Table 对象针对从 COM 对象返回的值执行自定义逻辑。
现在,您可以为 Table 对象编写独立的测试,同时使用 Mocks 模拟 COM 对象的行为。
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 对象。
希望这有帮助。
关于c# - 模拟 COM 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/304435/