题
我一直在研究一个只能获取和返回字符串的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对象。
希望这有帮助。
不隶属于 StackOverflow