How do I use Moq to mock an extension method?
Extension methods are just static methods in disguise. Mocking frameworks like Moq or Rhinomocks can only create mock instances of objects, this means mocking static methods is not possible.
How to properly mock extension methods with generics in xUnit?
Assuming you are using MOQ, do not try to mock the extension method.
Since you control the code of the extension method then mock a safe path through the extension method.
The extension uses GetAsync
in this case and that is what needs to be mocked assuming that is not an extension as well.
//...
_repository
.Setup(x => x.GetAsync(It.IsAny<Guid>()))
.ReturnsAsync(GetSamplePhase(newGuid));
//...
It will allow the test when exercised to go through GetActiveAsync
code and if it fails, also throw the Exceptions etc as described in the code.
Mock extension methods IElasticClient
Per @Olegl answer. It is not possible to Mock extension methods. You need to refactor and get rid of extension methods in order to make it testable
More info here
Creating a Moq of a static extension method from LLBLGen
You started with an extension method and then you created your IWrap
interface along with an implementation that uses the extension method. That's perfect.
Now all you need is to inject it into your class, just like IDataAccessAdapterProvider
is already injected:
public class QueryHandler
{
private readonly IDataAccessAdapterProvider _dataAccessAdapterProvider;
private readonly IWrap _wrap; //I'm assuming you'll want a different name.
public QueryHandler(IDataAccessAdapterProvider provider, IWrap wrap)
{
_dataAccessAdapterProvider = provider;
_wrap = wrap;
}
(I applied a common convention there. Prefixing the field names with an underscore - _wrap
- means that the field and constructor arguments have different names, so you don't need to specify this.wrap
. Plus when people see that underscore elsewhere they'll know it's a field.)
Now you can mock the interface:
var mock = new Mock<IWrap>();
var returnedFromMock = new List<int> { 1, 2, 3 };
mock.Setup(x => x.FetchQueryAsync<int>(It.IsAny<IDataAccessAdapter>(), It.IsAny<DynamicQuery<int>>()))
.ReturnsAsync(returnedFromMock);
You mentioned that there is no way you can change the code. I'm not sure which part you can't change, but if you can't change QueryHandler
to replace its concrete dependencies then this may just be a cautionary tale about static dependencies.
You have the source code, though. If you can't change the existing class, perhaps you can just create a new one from the existing source code. If someone asks why you duplicated an existing class, just say (tactfully) that you don't want to duplicate code - you'd rather fix the existing one so that it's testable.
Related Topics
How to Programmatically Generate Keypress Events in C#
Create Folder and File on Current User Profile, from Admin Profile
Easiest Way to Compare Arrays in C#
What Does Initializecomponent() Do, and How Does It Work in Wpf
Interop Type Cannot Be Embedded
Variable Scope Confusion in C#
How to Find the Most Recent File in a Directory Using .Net, and Without Looping
ASP.NET MVC Conditional Validation
No Connection Could Be Made Because the Target MAChine Actively Refused It 127.0.0.1:3446
What's the Difference Between Dynamic (C# 4) and Var
How to Shut Down the Computer from C#
How Using Try Catch for Exception Handling Is Best Practice
C# Reflection: How to Get Class Reference from String
Using Linq to Group a List of Objects into a New Grouped List of List of Objects
Parallel.Foreach VS Task.Factory.Startnew