views:

220

answers:

1

How would you check the parameters on a function that accepts a Dictionary?

IDictionary<string, string> someDictionary = new Dictionary<string, string> {
  {"Key1", "Value1"},
  {"Key2", "Value2"}
};

Expect.Call(delegate {someService.GetCodes(someDictionary);}).Constraints(...);

Basically, I want to verify that the parameter for GetCodes has the same values as the variable "someDictionary".

I forgot to mention that the method being tested builds the dictionary and passes that to the someService.GetCodes() method.

public void SomeOtherMethod() {
  IDictionary<string, string> dict = new Dictionary<string, string> {
    {"Key 1", "Value 1"},
    {"Key 2", "Value 2"}
  };

  someService.GetCodes(dict); // This would pass!

  IDictionary<string, string> dict2 = new Dictionary<string, string> {
    {"Key 1", "Value 1a"},
    {"Key 2a", "Value 2"}
  };

  someService.GetCodes(dict2); // This would fail!

}

so, I want to make sure the dictionary passed to the GetCodes method contain the same ones as the one specifed in the Expect.Call... method.

Another use case would be that maybe I just want to see if the keys of the dictionary contain "Key 1" and "Key 2", but don't care about the values... Or the othe rway around.

+2  A: 
// arrange
IDictionary<string, string> someDictionary = new Dictionary<string, string> {
  { "Key1", "Value1" },
  { "Key2", "Value2" }
};
ISomeService someService = MockRepository.GenerateStub<ISomeService>();

// act: someService needs to be the mocked object
// so invoke the desired method somehow
// this is usually done through the real subject under test
someService.GetCodes(someDictionary);

// assert
someService.AssertWasCalled(
    x => x.GetCodes(someDictionary)
);


UPDATE:

Here's how you could assert argument values:

someService.AssertWasCalled(
    x => x.GetCodes(
        Arg<IDictionary<string, string>>.Matches(
            dictionary => 
                dictionary["Key1"] == "Value1" && 
                dictionary["Key2"] == "Value2"
        )
    )    
);


UPDATE2:

As suggested by @mquander in the comments, the previous assert could be shortened using LINQ:

someService.AssertWasCalled(
    x => x.GetCodes(
        Arg<IDictionary<string, string>>.Matches(
            dictionary => 
                dictionary.All(pair => someDictionary[pair.Key] == pair.Value)
        )
    )
);
Darin Dimitrov
Not sure this is the solution I was looking for. What I want to check are the values in the dictionary, not necessarily that they are the same dictionary.
Bryce Fischer
If you check that it is the same dictionary reference this implies that it has the same values, thus putting values in the dictionary is not necessary. I've updated my post to show an example of how you could verify that a mocked object method has been called with some specific arguments.
Darin Dimitrov
I know nothing about Rhino Mocks, but couldn't you just replace the body of the predicate in the above "UPDATE" and change it to something like dictionary => dictionary.All(pair => someDict[pair.Key] == pair.Value) ?
mquander
Thanks Darin. That update is exactly what I was looking for.. Thanks!
Bryce Fischer
@mquander, yes indeed `dictionary.All` will work. I've added an UPDATE2.
Darin Dimitrov