Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moq, call base with constructor dependencies

I have a class

 public class Foo 
 {
      public Foo(IBar bar)
      {
         //...
      }
      public virtual int GetValue(){}
      public virtual DoActual()
      {
           ...
         var value = GetValue();
           ...
      }
 }

I need to test it. I want to override GetValue method and return particular value to caller. Here is my test code:

[TestMethod]
public void Test()
{
    var mock = new Mock<Foo>{ CallBase=true}; // problem is here
    mock.Setup(x=>x.GetValue()).Returns(1); 

    mock.DoActual();

 //asserts
}

Since my Foo class constructor has dependencies, I have to pass it into object initializer. Moq offers to pass arguments to params[] overload:

[TestMethod]
public void Test()
{
   var barMock= new Mock<IBar>();
    var mock = new Mock<Foo>(barMock){ CallBase=true}; // problem is still here
    mock.Setup(x=>x.GetValue()).Returns(1); 
    mock.DoActual();
 //asserts
}

When I pass my mock this way, I got error saying that Moq.Mock`1[IBar] is not that constructor of Foo accepting.

When I pass barMock.Object to constructor I get basically same error with different type:

"Could not find a constructor that would match given arguments:
 Castle.Proxies.IBarProxy"

I stuck in this place and don't know how to resolve my Foo class dependencies.

like image 673
Anton Shakalo Avatar asked Oct 24 '25 05:10

Anton Shakalo


1 Answers

Your minimised problem above doesn't compile, which suggests that you haven't tested it in it's current form. This makes it hard to tell if your actual issue is being correctly described or if you have reduced the problem too far and removed your actual problem, in which case you may want to edit your question to include additional details. The following code, based on the above compiles and works.

public interface IBar {
}

public class Foo 
{
   public Foo(IBar bar)
   {
       //...
   }
   public virtual int GetValue(){ return 0;}
   public virtual void DoActual()
   {
       var value = GetValue();
   }
}

[TestFixture]
public class SomeTests {
    [Test]
    public void TestMethodCalled() {
        var barMock = new Mock<IBar>();
        var mock = new Mock<Foo>(barMock.Object) { CallBase = true };
        mock.Setup(x => x.GetValue()).Returns(1);
        mock.Object.DoActual();
        //asserts
        mock.Verify(x => x.GetValue());
    }
}

It passes barMock.Object into the constructor, and verifies that the method has been called.

As has already been said, mocking the class you're testing is generally a bad idea, a better approach would be to manipulate/mock the dependencies of GetValue so that it returns the result you're after. Obviously your ability to do this will depend on what the method does and how much code you can change if necessary and sometimes, particularly with legacy code you just have to work with what you've got.

like image 63
forsvarir Avatar answered Oct 26 '25 19:10

forsvarir