I'm stucked with a Rhino Mock issue. I tried everything but my test always fails. The strange thing is that on last thursday I run the unit test alone and it worked. Then I run all the unit tests together and several were failed. (wtf??) One of them is the following:
public interface IOrder
{
Allocation GetAllocation();
Group GetParentGroup();
}
public class Order : IOrder
{
public virtual int Id { get; set; }
public virtual GroupMembership ParentGroupMembership { get; set; }
public virtual Allocation GetAllocation()
{
var parentGroup = GetParentGroup();
return parentGroup.GetAllocationForOrder( this );
}
public virtual Group GetParentGroup()
{
return ParentGroupMembership.ParentGroup;
}
}
public interface IGroupMembership
{
}
public class GroupMembership : IGroupMembership
{
public virtual int Id { get; set; }
public virtual Group ParentGroup { get; set; }
public virtual Order Order { get; set; }
}
public interface IGroup
{
Allocation GetAllocationForOrder( Order order );
}
public class Group : IGroup
{
public virtual int Id { get; set; }
public virtual ICollection<Allocation> Allocations { get; private set; }
public Group()
{
Allocations = new List<Allocation>();
}
public virtual Allocation GetAllocationForOrder( Order order )
{
return Allocations.Single( a => a.OrderId == order.Id );
}
}
public interface IAllocation
{
}
public class Allocation : IAllocation
{
public virtual int Id { get; set; }
public virtual int OrderId { get; set; }
}
[TestMethod]
public void TestGetAllocation()
{
var order = MockRepository.Stub<Order>();
order.Id = 1;
var parentGroupMembership = MockRepository.Stub<GroupMembership>();
parentGroupMembership.Id = 2;
var parentGroup = MockRepository.Stub<Group>();
parentGroup.Id = 3;
parentGroupMembership.ParentGroup = parentGroup;
order.ParentGroupMembership = parentGroupMembership;
var allocation = new Allocation { Id = 4, OrderId = 1 };
using ( MockRepository.Record() )
{
Expect.Call( order.GetParentGroup() ).Return( parentGroup );
Expect.Call( parentGroup.GetAllocationForOrder( order ) ).Return( allocation );
}
using ( MockRepository.Playback() )
{
var actual = order.GetAllocation();
Assert.IsNotNull( actual );
Assert.AreEqual( actual.OrderId, allocation.OrderId );
}
}
The problem is that the IsNotNull assert always fails. Why? In the recording section I set it to return with the child. I don't understand it. Maybe this happens because the Children collection, but in this case how could I mock that collection?
Many thanks, Maestro
You can only stub virtual methods with Rhino Mocks. So make sure that your GetChild metyhod is virtual, otherwide your Expect.Call( parent.GetChild( null ) ).Return( child );
makes no sense on a non-virtual method. You cannot define expectations on non-virtual members.
So try declaring the method as virtual:
public virtual Child GetChild(ChildIdentifier identifier)
Also the Record/Playback syntax in Rhino Mocks which you are using in your example has been deprecated in favor of the AAA syntax (actually this deprecation happened back in 2008 when the AAA syntax was introduced).
Also your unit test is difficult to understand. What exactly are you testing here? The method you are trying to unit test is the method you are defining expectations on - GetChild
. That's weird and not how mocking is intended to be used. You mock only dependencies that the method under test relies upon. You define expectations on those dependencies in order to guide the flow of the method under test and assert different scenarios.
UPDATE:
Instead of:
var order = MockRepository.Stub<Order>();
you should use:
var order = MockRepository.PartialMock<Order>();
in order to instantiate the subject under test.
If you use the Stub
method, the actual method that you are trying to unit test here (order.GetAllocation
) will never be hit.