Samuel
Samuel

Reputation: 12341

Optional parameters with a stub in RhinoMock

I want to stub a function that receive 2 boolean parameters. The first is required and the second is optional. If I try to send Arg.Is.Anything to the first but without information for the second, I receive an error:

System.InvalidOperationException : When using Arg, all arguments must be defined using Arg.Is, Arg.Text, Arg.List, Arg.Ref or Arg.Out. 2 arguments expected, 1 have been defined.

Here is a sample of my class to stub:

   public interface IOptionalParameterTester
   {
      bool IsValid(bool mustCheck, bool checkInDatabase = true);
   }

   public class OptionalParameterTester : IOptionalParameterTester
   {
      public bool IsValid(bool mustCheck, bool checkInDatabase = true)
      {
         if (checkInDatabase)
            return true;
         else
            return false;
      } 
   }

And here is a sample of the test:

  [Test]
  public void ValidateProducerTest()
  {
     IOptionalParameterTester optionalParameter = MockRepository.GenerateStub<IOptionalParameterTester>();

     optionalParameter.Stub(x => x.IsValid(Arg<bool>.Is.Anything)).Return(true);
  }

In this case, if I want the test to pass without error, I must define the same information that for the first (Arg.Is.Anything) or a specific boolean value like true or false.

If I set anything other than Arg.Is.Anything for the first parameter, I don't have any error.

Is it a bug?

Can I setup an option in RhinoMock to don't have to define a value for each optional parameter?

If there is no setup, is there a better thing to do to handle this case (Best practice, pattern, etc.)?

Thank you.

Upvotes: 4

Views: 3336

Answers (3)

nirmal
nirmal

Reputation: 1902

This is quite an old question now, but I landed on this page because I was having issues with AssertWasCalled and optional parameters.

Eventually, I solved my problem using the following syntax found on this page: http://petermorlion.blogspot.com/2012/11/rhinomock-assertwascalled-vs.html.

string expectedMessage = "RhinoMocks baby!";
string actualMessage = "RhinoMocks dude!";
var fooMock = MockRepository.GenerateMock<ifoo>();
fooMock.Bar(actualMessage);

var calls = fooMock.GetArgumentsForCallsMadeOn(x => x.Bar(string.Empty), o => o.IgnoreArguments());
Assert.AreEqual(1, calls.Count);
var arguments = calls[0];
Assert.AreEqual(expectedMessage, arguments[0]);

Upvotes: 0

pms1969
pms1969

Reputation: 3704

Just had a similar issue myself, try

optionalParameter.Stub(x => x.IsValid()).IgnoreArguments().Return(true);

Upvotes: 0

Sergio Romero
Sergio Romero

Reputation: 6597

I think I understand what you are trying to do but, since it seems that this is a limitation of Rhino Mocks (we can get to that conclusion from the error message you are receiving) I would suggest to change your testing strategy.

Try doing the following:

[Test]
  public void ValidateProducerTest()
  {
     bool anyBooleanValue = true;
     IOptionalParameterTester optionalParameter = MockRepository.GenerateStub<IOptionalParameterTester>();

     optionalParameter.Stub(x => x.IsValid(anyBooleanValue)).Return(true);
  }

I know that on your test you want Rhino Mocks to ignore the first parameter and that it takes the optional second one but, depending on the logic you want to test, just hard code the first parameter and Rhino Mocks should not complain.

As long as on your test it is clearly stated that the first parameter's value is not relevant your test is valid and readable.

Upvotes: 1

Related Questions