Unexpected behaviour from 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();
}
}
Allthough I have expected the Dispose()-Call, it is not recognized and I am getting the following message:
Rhino.Mocks.Exceptions.ExpectationViolationException: IDisposable.Dispose(); Expected #0, Actual #1.
If I rewirte the code without the using-clause everything is fine:
OracleCommand cmd = null;
try {
command = connection.CreateCommand();
...
command.ExecuteNonQuery();
}
finally {
if (command != null)
command.Dispose();
}
Any ideas on this issue?
Regards, MacX
This question and answer suggest that the problem may stem from the fact that you are stubbing out OracleCommand
, rather than an IDbCommand or similar.
The comments on the accepted answer suggest that if OracleCommand
is an abstract class, you should be mocking it using GeneratePartialMock<OracleCommand>()
.
I hope this helps you.
In response to your comment, it sounds like you need the implementation-specific methods of OracleCommand
, but can't mock it properly.
Although OracleCommand
is sealed, you could wrap it compositionally. It takes some legwork, but will allow you to both use OracleCommand
in your code and mock it in your tests.
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; }
}
}
Now you can use IOracleCommand
and OracleCommandWrapper
in your code, and in your tests you just mock or stub off of the IOracleCommand
interface.
Again, it takes some legwork, but gets you where you want to be.