RhinoMocks意外处理()

时间:2011-05-24 14:25:12

标签: c# rhino-mocks

RhinoMocks的意外行为:

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();
    }
}

尽管我已经预料到Dispose() - Call,但它无法识别,我收到以下消息:

Rhino.Mocks.Exceptions.ExpectationViolationException: IDisposable.Dispose(); Expected #0, Actual #1.

如果我在没有using子句的情况下重新编写代码,一切都很好:

OracleCommand cmd = null;
try {
    command = connection.CreateCommand();
    ...
    command.ExecuteNonQuery();
}
finally {
    if (command != null)
        command.Dispose();
}

关于这个问题的任何想法?

此致 的MacX

1 个答案:

答案 0 :(得分:2)

This question and answer表明问题可能源于您正在查找OracleCommand,而不是IDbCommand或类似内容。

对已接受答案的评论表明,如果OracleCommand是抽象类,则应使用GeneratePartialMock<OracleCommand>()进行嘲弄。

我希望这会对你有所帮助。

修改

在回复您的评论时,听起来您需要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; }
    }
}

现在,您可以在代码中使用IOracleCommandOracleCommandWrapper,在测试中,您只需模拟或存根IOracleCommand界面。

同样,它需要一些腿部工作,但能让你到达目的地。