Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking of extension method result in System.NotSupportedException

I'm unit testing a ClientService that uses the IMemoryCache interface:

ClientService.cs:

public string Foo()
{        
    //... code

    _memoryCache.Set("MyKey", "SomeValue", new TimeSpan(0, 0, 60));
}

When I try to mock the IMemoryCache's Set extension with:

AutoMock mock = AutoMock.GetLoose();

var memoryCacheMock = _mock.Mock<IMemoryCache>();

string value = string.Empty;

// Attempt #1:
memoryCacheMock
     .Setup(x => x.Set<string>(It.IsAny<object>(), It.IsAny<string>(), It.IsAny<TimeSpan>()))
     .Returns("");

// Attempt #2:
memoryCacheMock
    .Setup(x => x.Set(It.IsAny<object>(), It.IsAny<object>(), It.IsAny<TimeSpan>()))
    .Returns(new object());

It throw an exception of:

System.NotSupportedException: Unsupported expression: x => x.Set(It.IsAny(), It.IsAny(), It.IsAny()) Extension methods (here: CacheExtensions.Set) may not be used in setup / verification ex

This is the Cache extension of the namespace Microsoft.Extensions.Caching.Memory

public static class CacheExtensions
{
   public static TItem Set<TItem>(this IMemoryCache cache, object key, TItem value, TimeSpan absoluteExpirationRelativeToNow);
}
like image 783
Shahar Shokrani Avatar asked Aug 29 '19 07:08

Shahar Shokrani


People also ask

Can extension methods be mocked C#?

Remember that the extension method cannot be mocked; unit tests for a class that is using it will test both this class logic and extension method's logic.

What are extension methods in C# stack overflow?

Extension methods are ways for developers to "add on" methods to objects they can't control. For instance, if you wanted to add a "DoSomething()" method to the System. Windows. Forms object, since you don't have access to that code, you would simply create an extension method for the form with the following syntax.

How do you mock Imemorycache?

Given that it is not feasible to mock extension methods with Moq, Try mocking the interface members that are accessed by the extension methods. Referring to Moq's quickstart update MockMemoryCacheService to properly setup the TryGetValue method for the test.

Is it possible to mock set() method in EXT extension?

Extension methods are actually static methods and they cannot be mocked using moq. What you could mock are the methods used by the extension method itself... In your case Set uses CreateEntry which is the method defined by IMemoryCache and it could be mocked.

Is it possible to mock the extension method of cacheextensions?

public static class CacheExtensions { public static TItem Set<TItem> (this IMemoryCache cache, object key, TItem value, TimeSpan absoluteExpirationRelativeToNow); } You cannot mock extension method, I guess behind the Set is actually CreateEntry which actually should have been mocked...

What is mocking extension methods in Telerik JustMock?

Mocking extension methods is one of the advanced features supported in Telerik® JustMock. In this topic, we will go through some examples that show how easy and straightforward it is to assert expectations related to extension methods in your tests. This feature is available only in the commercial version of Telerik JustMock.

Is there a way to mock the executesqlcommand method?

Is there a way to mock the ExecuteSQLCommand method directly? It is not possible to mock it directly as it is an extension method. It is possible to mock what that extension method invokes though and mock it indirectly. I had a similar case and ended up implementing EntityFrameworkCore.Testing as it's a pretty involved Moq set up.


1 Answers

Extension methods are actually static methods and they cannot be mocked using moq. What you could mock are the methods used by the extension method itself...

In your case Set uses CreateEntry which is the method defined by IMemoryCache and it could be mocked. Try something like this:

memoryCacheMock
    .Setup(x => x.CreateEntry(It.IsAny<object>()))
    .Returns(Mock.Of<ICacheEntry>);
like image 163
Johnny Avatar answered Nov 14 '22 22:11

Johnny