tpdi
tpdi

Reputation: 35141

RhinoMocks and Abstract Base Classes

I'm trying to mock using System.Security.Cryptography.RandomNumberGenerator, which unfortunately is an abstract base class, not an interface.

When I try to set up an expectation in Rhino.Mocks:

int iterations = 10 ;
byte[] fakeHash = {0, 1, 3, 6};
mocks.Get<HashAlgorithm>().Expect(x => x.ComputeHash(Arg<byte[]>.Is.NotNull))
    .Return(fakeHash).Repeat.Times(iterations);

I get an exception thrown from the ABC:

Test method Tests.Utils.FooTest.BarTest threw exception: System.ArgumentNullException: Value cannot be null. Parameter name: buffer at System.Security.Cryptography.HashAlgorithm.ComputeHash(Byte[] buffer)

The ABC is enforcing the invariant that passed argument is not null, but Rhino is passing a null. Note that this happens as part of the setup of the expectation/stub, not when it's called as part of the test.

How can I work around this, but still get both the Expectation that the method will be called, and the fake result I want? I could just make my own mock class, of course, but I'd prefer to find a way to do this that doesn't require that.

Thanks.

Upvotes: 1

Views: 291

Answers (2)

Ed Chapel
Ed Chapel

Reputation: 6932

Unfortunately, the HashAlgorithm.ComputeHash methods are not virtual and cannot be mocked by RhinoMocks.

public byte[] ComputeHash(Stream inputStream) { ... }
public byte[] ComputeHash(byte[] buffer) { ... }
public byte[] ComputeHash(byte[] buffer, int offset, int count)

Upvotes: 0

the_joric
the_joric

Reputation: 12226

Exception is thrown because ComputeHash is not a virtual member. You can set expectations only on virtual or interface methods. If you need to mock this class you need to create a wrapper with virtual members and mock it instead of real class.

Note that if you have a resharper -- that is trivial, just create a class, put HashAlgorithm as a field and select Generate / Delegating Methods. Then choose methods you need to mock and make them virtual :)

Upvotes: 2

Related Questions