I am trying to assert that a property in a mock object was set with a given type. The property has an abstract type and is set with one of a number of concrete types.
This is what I'm trying to do, and it's always passing the test regardless of the value that Foo.DoSomething() sets Foo.Bar with:
[Test]
public void DoSomething_SetsCorrectBar()
{
// Arrange
Foo foo = MockRepository.GenerateMock<Foo>(); // Creates mock in Replay mode (what I want for AAA syntax).
// Act
foo.DoSomething();
// Assert that DoSomething set Foo.Bar to an instance of CorrectBarSubclass
foo.AssertWasCalled(foo => foo.Bar = null, options => options.WhenCalled(invocation => Assert.That(invocation.Arguments[0] is CorrectBarSubclass)));
}
The Rhino 3.5 / AAA Documentation describes how to set expectations on property sets having a given value, but I just want to check the type of the value.
How does one assert on a property set, specifically on a property set having a given parameter type?
Update: The example above is oversimplified. What I'm actually testing is an individual state class. It's one of several states that a "parent object" (the object having the state, Foo in this case) can be in. I was verifying that the state under test (call it BarOne) correctly set Foo.State to an instance of BarTwo when it was time to transition states.
A clearer example (with the accepted solution implemented) would be:
[Test]
public void BarOne_DoSomething_SetsNextState()
{
// Arrange
Foo foo = MockRepository.GenerateMock<Foo>(); // Creates mock in Replay mode (what I want for AAA syntax).
foo.Stub(x => x.CreateBarTwoState()).Return(new BarTwo(foo));
BarOne bar = new BarOne(foo); // We are testing the BarOne state independently of Foo, that's why we mock Foo but instantiate BarOne.
// Act
bar.DoSomething();
// Assert that DoSomething set Foo.Bar to an instance of BarTwo
foo.AssertWasCalled(foo => foo.Bar = Arg<BarTwo>.Is.TypeOf);
}
Perhaps something like this:
[Test]
public void AddPlayer_GivesGameEnoughPlayersToStart_SetsNextState()
{
// Arrange
Foo foo = MockRepository.GenerateMock<Foo>(); // Creates mock in Replay mode (what I want for AAA syntax).
foo.Expect(m => m.Bar = Arg<CorrectBarSubclass>.Is.TypeOf);
// Act
foo.DoSomething();
//Assert
foo.VerifyAllExpectations();
}
So what's going on..
We changed the assertion to be an Expect. I find this a little bit cleaner, also the expectation allows us a cleaner verification of what the type is. We are Saying "Expect that Bar
will be set to an instance of CorrectBarSubclass
. Then we Act, and we assert that our expectation was met.
Couple of things: Any time you Mock a class, anything you have an Expect
or Stub
call on must be virtual or abstract, so in this case, Bar
must be virtual. It's usually always better to mock an interface and test how a class uses a dependency, rather than testing how a class uses itself (that usually is an indication of over-testing, or incorrect separation of concerns).
In your case, is a mock even required? You are just using a somewhat complicated syntax to assert the result of a real behavior, nothing is really mocked other than the setter of a property. Sometimes it's just easier, and more appropriate, to test real behaviors. Why not do something like this:
var foo = new Foo();
foo.DoSomething();
Assert.That(foo.Bar is CorrectBarSubclass);