Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock a class that implements multiple interfaces

Tags:

c#

mocking

moq

How to mock the following class:

UserRepository : GenericRepository<User>, IUserRepository   public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class 

I am using Moq, and I am confused how to handle multiple interfaces correctly.

like image 354
loyalflow Avatar asked Apr 04 '13 20:04

loyalflow


People also ask

How do you mock a class that implements two interfaces?

You can implement multiple interfaces with a single mock instance like this: var genericRepositoryMock = new Mock<IGenericRepository<User>>(); genericRepositoryMock. Setup(m => m. CallGenericRepositoryMethod()).

Can we create mock for interface?

mock() The Mockito. mock() method allows us to create a mock object of a class or an interface. We can then use the mock to stub return values for its methods and verify if they were called.

Can you mock a class 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. However, there are a few limitations you should be aware of. The classes to be mocked can't be static or sealed, and the method being mocked should be marked as virtual.

How do I mock a class without an interface?

Simply mark any method you need to fake as virtual (and not private). Then you will be able to create a fake that can override the method.


2 Answers

Take a look at https://github.com/Moq/moq4/wiki/Quickstart

Advanced Features

// implementing multiple interfaces in mock var foo = new Mock<IFoo>(); var disposableFoo = foo.As<IDisposable>(); // now IFoo mock also implements IDisposable :) disposableFoo.Setup(df => df.Dispose()); 
like image 175
ShloEmi Avatar answered Oct 06 '22 00:10

ShloEmi


There is a mechanism built into Moq for dealing with multiple interfaces.

Say we have an interface IFoo and an implementation of the same Foo. We also have ClientOne that uses IFoo.

We then have an interface IFooBar : IFoo, an implementation FooBar : Foo, IFooBar and a ClientTwo that uses IFooBar.

When creating an end-to-end test for the system we have an IFooBar, ClientOne and ClientTwo. The As<>() function allows us to use the Mock<IFooBar> as a Mock<IFoo>.

public interface IFoo {     int Id { get; } }  public class Foo : IFoo {     public int Id {         get { return 1; }     } }  public interface IFooBar : IFoo  {     string Name { get; } }  public class FooBar : Foo, IFooBar {     public string Name {         get { return "AName"; }     } }  public class ClientOne {     private readonly IFoo foo;      public ClientOne(IFoo foo) {         this.foo = foo;     }      public string Details {         get { return string.Format("Foo : {0}", foo.Id); }     }  }  public class ClientTwo {     private readonly IFooBar fooBar;      public ClientTwo(IFooBar fooBar) {         this.fooBar = fooBar;     }      public string Details {         get { return string.Format("Foo : {0}, Bar : {1}", fooBar.Id, fooBar.Name); }     }  }   [TestMethod] public void TestUsingBothClients() {      var fooBarMock = new Mock<IFooBar>();     var fooMock = fooBarMock.As<IFoo>();      fooBarMock.SetupGet(mk => mk.Id).Returns(1);     fooBarMock.SetupGet(mk => mk.Name).Returns("AName");      var clientOne = new ClientOne(fooMock.Object);     var clientTwo = new ClientTwo(fooBarMock.Object);      Assert.AreEqual("Foo : 1", clientOne.Details);     Assert.AreEqual("Foo : 1, Bar : AName", clientTwo.Details);  } 
like image 21
AlanT Avatar answered Oct 05 '22 23:10

AlanT