Passing Moq mock-objects to constructor

29,944

Solution 1

You need to pass through the object instance of the mock

var mock = new Mock<IBar>();  
var foo = new Foo(mock.Object);

You can also use the the mock object to access the methods of the instance.

mock.Object.GetFoo();

moq docs

Solution 2

var mock = new Mock<IBar>().Object

Solution 3

The previous answers are correct but just for the sake of completeness I would like add one more way. Using Linq feature of the moq library.

public interface IBar
{
    int Bar(string s);

    int AnotherBar(int a);
}

public interface IFoo
{
    int Foo(string s);
}

public class FooClass : IFoo
{
    private readonly IBar _bar;

    public FooClass(IBar bar)
    {
        _bar = bar;
    }

    public int Foo(string s) 
        => _bar.Bar(s);

    public int AnotherFoo(int a) 
        => _bar.AnotherBar(a);
}

You could use Mock.Of<T> and avoid .Object call.

FooClass sut = new FooClass(Mock.Of<IBar>(m => m.Bar("Bar") == 2 && m.AnotherBar(1) == 3));
int r = sut.Foo("Bar"); //r should be 2
int r = sut.AnotherFoo(1); //r should be 3

or using matchers

FooClass sut = new FooClass(Mock.Of<IBar>(m => m.Bar(It.IsAny<string>()) == 2));
int r = sut.Foo("Bar"); // r should be 2
Share:
29,944

Related videos on Youtube

stiank81
Author by

stiank81

System Developer mainly living in the .Net-world. Coding in C#, Javascript, html, css, ..

Updated on July 05, 2022

Comments

  • stiank81
    stiank81 almost 2 years

    I've been using RhinoMocks for a good while, but just started looking into Moq. I have this very basic problem, and it surprises me that this doesn't fly right out of the box. Assume I have the following class definition:

    public class Foo
    {
        private IBar _bar; 
        public Foo(IBar bar)
        {
            _bar = bar; 
        }
        ..
    }
    

    Now I have a test where I need to Mock the IBar that send to Foo. In RhinoMocks I would simply do it like follows, and it would work just great:

    var mock = MockRepository.GenerateMock<IBar>(); 
    var foo = new Foo(mock); 
    

    However, in Moq this doesn't seem to work in the same way. I'm doing as follows:

    var mock = new Mock<IBar>(); 
    var foo = new Foo(mock); 
    

    However, now it fails - telling me "Cannot convert from 'Moq.Mock' to 'IBar'. What am I doing wrong? What is the recommended way of doing this with Moq?

  • stiank81
    stiank81 almost 13 years
    +1 for being only 10 seconds behind the answer that will be the accepted one. Thx!
  • skyfoot
    skyfoot almost 13 years
    I would not normally assign the object instance to a variable like this as you may want to setup the mock for specific behaviour.
  • Massimiliano Peluso
    Massimiliano Peluso almost 13 years
    it was just to show .Object which was the solution to the run-time error he was having :-)
  • ulkas
    ulkas about 5 years
    how do i specify several methods/params in the mocked definition? something like new FooClass(Mock.Of<IBar>(m => m.Bar("Bar") == 2, k => k.Ready() == true ));
  • Johnny
    Johnny about 5 years
    @ulkas You should use &&, I have updated the answer, FooClass(Mock.Of<IBar>(m => m.Bar("Bar") == 2 && m.Ready() == true ));
  • Shimmy Weitzhandler
    Shimmy Weitzhandler almost 4 years
    But I need mock.Object to be initialized only when I'm calling foo.Object. What I'm basically looking for is the ability to pass to Foo's constructor, the raw Mock<IBar>, to be called when I call mock.Object. Is there a way to achieve this?