Search code examples
c#unit-testingmockingrhino-mocks

Rhinomock non-primitive object in expectations


it seems comments can't support code

Lets say I call a method (e.g. SaveTicket) and have used constructor(e.g. Repository, Logging) to inject various mock interfaces. If that method calls another object and creates a non-primitive object inside that method. Is there any easy way to test the values of that non-primitive object?

I guess trying to replace that non-primitive object with property and injecting is possible, or Using LastCall.Constraints. Is there a better way?

Here is an example - in the below example - in order to verify Repository.save(t);

is called with correct values of t I can

  1. Do lastcall.constraints

  2. lastcall.ignorearguments

Is there a better way?

CreateMyTicket(int ticketnumber, string name)
{
   ticketobject t = new ticketObject(ticketnumber, name);
   t.upgrade = ticketnumber+2;
   Repository.save(t);
}

Solution

  • Let's take an example. Suppose that you have the following class and you want to unit test the CreateMyTicket method:

    public class ClassToTest
    {
        public IRepository Repository { get; private set; }
    
        public ClassToTest(IRepository repository)
        {
            Repository = repository;
        }
    
        public void CreateMyTicket(int ticketnumber, string name)
        {
            var t = new TicketObject(ticketnumber, name);
            t.Upgrade = ticketnumber + 2;
            Repository.Save(t);
        }
    }
    

    This assumes that we have an IRepository interface:

    public interface IRepository
    {
        void Save(TicketObject t);
    }
    

    and here's how a sample unit test could look like:

    [TestMethod]
    public void CreateMyTicketTest() 
    {
        // arrange
        var repositoryStub = MockRepository.GenerateStub<IRepository>();
        var sut = new ClassToTest(repositoryStub);
        var ticketNumber = 5;
        var name = "John";
    
        // act
        sut.CreateMyTicket(ticketNumber, name);
    
        // assert
        repositoryStub.AssertWasCalled(
            x => x.Save(
                Arg<TicketObject>.Matches(t => 
                    t.Upgrade == 7 && 
                    t.Name == name && 
                    t.TicketNumber == ticketNumber
                )
            )
        );
    }