C# RhinoMocks意外处置()
Rhinomock的意外行为:C# RhinoMocks意外处置(),c#,rhino-mocks,C#,Rhino Mocks,Rhinomock的意外行为: var mocks = new MockRepository(); var connection = mocks.Stub<OracleConnection>(); var command = mocks.Stub<OracleCommand>(); using (mocks.Record()) { connection.Expect(x => x.CreateCommand()).Return(command);
var mocks = new MockRepository();
var connection = mocks.Stub<OracleConnection>();
var command = mocks.Stub<OracleCommand>();
using (mocks.Record()) {
connection.Expect(x => x.CreateCommand()).Return(command);
command.Expect(x => x.ExecuteNonQuery());
command.Expect(x => x.Dispose());
}
using (mocks.Playback()) {
using(var command = connection.CreateCommand()) {
...
command.ExecuteNonQuery();
}
}
如果我在没有using子句的情况下重新编写代码,一切正常:
OracleCommand cmd = null;
try {
command = connection.CreateCommand();
...
command.ExecuteNonQuery();
}
finally {
if (command != null)
command.Dispose();
}
对这个问题有什么想法吗
问候,,
MacX表明问题可能源于这样一个事实,即您正在删除OracleCommand
,而不是IDbCommand或类似命令
接受答案上的注释表明,如果OracleCommand
是一个抽象类,那么应该使用GeneratePartialMock()
模拟它
我希望这对你有帮助
编辑
作为对您的评论的回应,听起来您需要OracleCommand
的特定于实现的方法,但无法正确地模拟它
虽然OracleCommand
是密封的,但您可以将其组合包装。这需要一些准备工作,但将允许您在代码中使用OracleCommand
,并在测试中模拟它
public interface IOracleCommand : IDbCommand
{
void OracleMethod();
string OracleProperty { get; set; }
}
public class OracleCommandWrapper : IOracleCommand
{
private OracleCommand _inner;
public OracleCommandWrapper(OracleCommand inner)
{
_inner = inner;
}
public void Dispose()
{
_inner.Dispose();
}
public IDbDataParameter CreateParameter()
{
return _inner.CreateParameter();
}
// do this for all the members, including the Oracle-specific members
public void OracleMethod()
{
_inner.OracleMethod();
}
public string OracleProperty
{
get { return _inner.OracleProperty; }
set { _inner.OracleProperty = value; }
}
}
现在,您可以在代码中使用IOracleCommand
和OracleCommandWrapper
,在测试中,您只需模拟或删除IOracleCommand
接口
同样,这需要一些准备工作,但可以让您达到您想要的目的。由于OracleConnection类和其他类是密封的,我在创建模拟时收到一条“System.NotSupportedException:无法创建密封类的模拟”消息。所以这不是一个机会。否则,直接测试数据库并不是我真正想要的want@MacX-OracleConnection派生自DbConnection,后者实现IDbConnection。这是您想要模拟和注入的接口,而不是创建OracleConnection的实例/mock/stub/等。一般来说,这是一个机会。但事实上,我需要Oracle实现提供的一些特殊功能,例如用于大型插入的arraybinding——我认为这对于我的需求来说是相当大的开销。虽然这个问题并没有让我比重写using子句做更多的事情,但我更喜欢重写而不是包装Oracle,不过还是非常感谢
public interface IOracleCommand : IDbCommand
{
void OracleMethod();
string OracleProperty { get; set; }
}
public class OracleCommandWrapper : IOracleCommand
{
private OracleCommand _inner;
public OracleCommandWrapper(OracleCommand inner)
{
_inner = inner;
}
public void Dispose()
{
_inner.Dispose();
}
public IDbDataParameter CreateParameter()
{
return _inner.CreateParameter();
}
// do this for all the members, including the Oracle-specific members
public void OracleMethod()
{
_inner.OracleMethod();
}
public string OracleProperty
{
get { return _inner.OracleProperty; }
set { _inner.OracleProperty = value; }
}
}