Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking objects with Moq when constructor has parameters

Tags:

moq

I have an object I'm trying to mock using moq. The object's constructor has required parameters:

public class CustomerSyncEngine {     public CustomerSyncEngine(ILoggingProvider loggingProvider,                                ICrmProvider crmProvider,                                ICacheProvider cacheProvider) { ... } } 

Now I'm trying to create the mock for this object using either moq's v3 "setup" or v4 "Mock.Of" syntax but can't figure this out... everything I'm trying isn't validating. Here's what I have so far, but the last line is giving me a real object, not the mock. The reason I'm doing this is because I have methods on the CustomerSyncEngine I want to verify are being called...

// setup var mockCrm = Mock.Of<ICrmProvider>(x => x.GetPickLists() == crmPickLists); var mockCache = Mock.Of<ICacheProvider>(x => x.GetPickLists() == cachePickLists); var mockLogger = Mock.Of<ILoggingProvider>();  // need to mock the following, not create a real class like this... var syncEngine = new CustomerSyncEngine(mockLogger, mockCrm, mockCache); 
like image 828
Andrew Connell Avatar asked Sep 14 '11 10:09

Andrew Connell


People also ask

Can we mock constructor using Mockito?

Starting with Mockito version 3.5. 0, we can now mock Java constructors with Mockito. This allows us to return a mock from every object construction for testing purposes.

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 you create a object in MOQ?

Simpler mock objects, using MoqRight-click on the TestEngine project (the one we want to add Moq to). Select “Manage NuGet Packages…” In the NuGet tab, select “Browse” and search for “Moq” – the library we want to add. There are several add-on libraries that make it easier to use Moq in different types of programs.


2 Answers

Change the last line to

var syncEngine = new Mock<CustomerSyncEngine>(mockLogger, mockCrm, mockCache).Object; 

and it should work

like image 174
Suhas Avatar answered Sep 24 '22 10:09

Suhas


The last line is giving you a real instance because you are using the new keyword, not mocking CustomerSyncEngine.

You should use Mock.Of<CustomerSyncEngine>()

The only problem with Mocking Concrete types is that Moq would need a public default constructor(with no parameters) OR you need to create the Moq with constructor arg specification. http://www.mockobjects.com/2007/04/test-smell-mocking-concrete-classes.html

The best thing to do would be right click on your class and choose Extract interface.

like image 28
Raghu Avatar answered Sep 25 '22 10:09

Raghu