Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking a return type from another Mocked type using Moq

Tags:

c#

mocking

moq

So I'm trying to return a mocked type from another Mocked type, I've made some progress but I'm stuck here (interface names have been simplified)

Consider the interface IFoo and IFooItem. Calling Add on an IFoo type, passing in an IBar returns an IFooItem

interface IFoo
{
   IFooItem Add(IBar bar);
}

interface IFooItem
{
   int fooItemId {get; set;}
}

Also I have a IFooRepository, which I'm trying to use Moq to mock so I can mock adding an item.

So,

var mockFooRepository = new Mock<IFooRepository>();
mockFooRepository.Setup(m=> m.Add(It.IsAny<IBar>()))
  .Returns(
     // What is the correct way to mock properties of a new IFooItem from 
     // mocked properties of IBar
     // essentially a new mocked type of IFooItem that can read from IBar
     // so IFooItem.Property = somevalue, IFooItem.Property2 = IBar.SomeProp
     );
like image 567
Ta01 Avatar asked Apr 24 '12 23:04

Ta01


People also ask

How do you mock a method in Moq?

First, we instantiate the FakeDbArticleMock class and indicate which setup we want to use for this test. Then, it is necessary to instantiate the repository we want to test and inject the mock instance into it. Finally, we call the method we are testing and assert the results.

How do you return different values each time a mocked method is called?

The alternative is to use the Moq feature Sequence which allows you to set multiple return values, that will be returned one at a time in order, each time the mocked method is called.

What can be mocked with Moq?

You can use Moq to create mock objects that simulate or mimic a real object. Moq can be used to mock both classes and interfaces.

What is Callbase in Moq?

The Callbase property is a boolean and decides whether or not to call the base member virtual implementation. And update the method signature to virtual. Then we put it all together. If you run through this test you will now see that the same class will return a mock value.


1 Answers

Something like this should work:

var mockFooRepository = new Mock<IFooRepository>();
mockFooRepository.Setup(r => r.Add(It.IsAny<IBar>()))
    .Returns<IBar>(bar => 
    {
        var item = new Mock<IFooItem>();

        item.Setup(i => i.fooItemId)
            .Returns(bar.Id);
            
        return item.Object;
    });

This assumes that IBar looks like this:

public interface IBar 
{
    int Id { get; set; }
}
like image 147
Andrew Whitaker Avatar answered Sep 28 '22 03:09

Andrew Whitaker