I'm trying to Setup the return of a call to an extension method and am receiving:
SetUp : System.NotSupportedException : Expression references a method that does not belong to the mocked object: m => m.Cache.GetOrStore<String>("CacheKey", () => "Foo", 900)
It seems to have a problem with referencing the GetOrStore method on the Cache object which is an extension method.
The code compiles but the test fails with this exception.
What do I need to do to setup the result of an extension method like this?
Extension methods can not be mocked like instance methods because they are not defined on your mocked type. They are defined in other static classes. Since you can't simply mock those, you should mock all methods/properties used by the extension method.
This is an example of how extension methods tightly couples your code to other classes. Whatever you do, your class depends on those static methods. You can't mock it and test it in isolation. I suggest refactoring your code to move those methods to their classes of their own if there is any logic inside.
Moq cannot mock static methods, therefore you won't be able to mock your GetOrStore extension.
Instead just mock the Get and Insert methods of the Cache object.
It is possible, although not pretty...
I assume there is some internal cache object inside your extension method, or a reference to some cache somewhere. You can use reflection to replace the internal object to store the cache. You get something like this inside your test:
IFixture fixture = new Fixture().Customize(new AutoMoqCustomization());
Mock<ICache> internalCache = new Mock<ICache>();
internalCache.Setup(i => i.Get<String>("CacheKey")).Returns("Foo");
var cacheExtension = typeof(CacheExtensions);
var inst = cacheExtension.GetField("_internalCache", BindingFlags.NonPublic | BindingFlags.Static);
inst.SetValue(cacheExtension, internalCache.Object);
Note that this code is not tested, but it should explain the basic idea.
Related
I have an api service that calls another api service. When I set up the Mock objects, it failed with an error:
NotSupportedException: expression references a method that does not belong to the mocked object.
This is the code:
private Mock<IEnumerable<ICarrierApiService<AccountSearchModel>>> _mockCarrierService;
private Mock<IApiService<AccountSearchModel>> _mockApiService;
[SetUp]
public void SetUp()
{
_mockApiService = new Mock<IApiService<AccountSearchModel>>();
_mockCarrierService = new Mock<IEnumerable<ICarrierApiService<AccountSearchModel>>>();
_mockApiService.Setup(x => x.GetFromApiWithQuery(It.IsAny<string>())).Returns(ApiValue());
// Error occurred when call _mockApiService.GetFromApiWithQuery() in .Select()
_mockCarrierService.Setup(x => x
.Select(s => s
.GetFromApiWithQuery(It.IsAny<string>())).ToList())
.Returns(new List<IQueryable<AccountSearchModel>> { ApiValue() });
}
I read Expression testing with Moq but it didn't work for my case. If I remove this _mockCarrierService.Setup(), the test case can run but fails with a NullReferenceException because it didn't have a valid List<IQueryable<AccountSearchModel>> set up.
Any idea how I can achieve this?
Footnote: Current Solution
FWIW, here's the solution that I currently use. I am all ears for a better approach to the issue (until Moq starts supporting mocking extension methods).
private List<ICarrierApiService<AccountSearchModel>> _mockCarrierService;
private AccountSearchController _mockController;
private Mock<ICarrierApiService<AccountSearchModel>> _mockApiService;
[SetUp]
public void SetUp()
{
_mockApiService = new Mock<ICarrierApiService<AccountSearchModel>>();
_carrierServiceMocks = new List<ICarrierApiService<AccountSearchModel>> { _mockApiService.Object };
_mockApiService.Setup(x => x.GetFromApiWithQuery(It.IsAny<string>())).Returns(ApiValue());
_mockController = new AccountSearchController(_carrierServiceMocks);
}
Footnote: alternative mocking framework
I've also found a commercial mocking framework that supports mocking extension method and link to the how-to docs: Telerik JustMock.
This problem occurs because you are trying to mock Select method, which is an extension method, not an instance method of IEnumerable<T>.
Basically, there is no way to mock an extension method. Have a look at this question for some ideas that you may find useful.
UPD (12/11/2014):
To gain more understanding on mocking extension methods, think about the following:
Although extension methods are called as if they were instance methods on the extended type, they are actually just a static methods with a bit of syntactic sugar.
Extension methods from System.Linq namespace are implemented as pure functions — they are deterministic and they don't have any observable side effects. I agree that static methods are evil, except those that are pure functions — hope you would agree with this statement too :)
So, given an object of type T, how would you implement static pure function f(T obj)? It is only possible by combining other pure functions that are defined for object T (or any other pure functions, actually), or by reading immutable and deterministic global state (to keep function f deterministic and side-effect-free). Actually, "immutable and deterministic global state" has more convenient name — a constant.
So, it turns out that if you follow the rule that static methods should be pure functions (and it looks like Microsoft follows this rule, at least for the LINQ methods), mocking an extension method f(this T obj) should be reducible to mocking non-static methods or state used by that extension method — simply because that extension method relies on the obj instance methods and state in its implementation (and possibly on the other pure functions and/or constant values).
In case of IEnumerable<T>, Select() extension method is implemented in terms of foreach statement which, in turn, uses GetEnumerator() method. So you can mock GetEnumerator() and achieve required behavior for extension methods that rely on it.
You have:
_mockCarrierService = new Mock<IEnumerable<ICarrierApiService<AccountSearchModel>>>();
So you mock IEnumerable<>. The only member IEnumerable<> has is a method GetEnumerator() (plus another method with the same signature GetEnumerator() inherited from the base interface). The Select method is really an extension method (as was pointed out in the first answer) which is a static method that works by calling GetEnumerator() (possibly through C# foreach statement).
It is possible to make things work by doing Setup of GetEnumerator on your mock.
However, it is much simpler to simply use a concrete, non-mock type which "is" IEnumerable<>, such as List<>. So try:
_mockCarrierService = new List<ICarrierApiService<AccountSearchModel>>();
Then add an entry to the List<>. What you should add, is a Mock<ICarrierApiService<AccountSearchModel>> on which GetFromApiWithQuery Method is setup.
also if u need to Mock IConfiguration u can use this code below:
var builder = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string>
{
{ "your-key", "your value" }
});
var config = builder.Build();
Since the question about mocking IConfiguration is referring this answer as duplicate, I will contribute my dime here.
This is how I "Mock" IConfiguration, which is, in my opinion, a bit cleaner:
private static IConfiguration GetConfigurationMock(string jsonConfiguration)
{
var byteArray = Encoding.UTF8.GetBytes(jsonConfiguration);
var stream = new MemoryStream(byteArray);
var conf = new ConfigurationBuilder();
conf.AddJsonStream(stream);
var confRoor = conf.Build();
return confRoor;
}
Original question: How to setup Mock of IConfigurationRoot to return value
I'm trying to unit test a method and mock the method call inside it:
class LoginViewModel
{
public bool LogUserIn(string hashedPassword)
{
//Code
if (loginSuccessful)
{
GoToMainMenu(); // I WANT TO MOCK THIS CALL.
return true;
}
return false;
}
}
so I want to mock the GoToMainMenu() function call, as this is only for navigation and I get an exception thrown here when I try to run my test.
I've tried using NUnit.Mocks:
[Test]
public void Log_User_In_Will_Return_True()
{
DynamicMock mockView = new DynamicMock(typeof(LoginViewModel));
mockView.ExpectAndReturn("GoToMainMenu", null);
LoginViewModel loginVM = (LoginViewModel)mockView.MockInstance; //ArgumentException
Assert.AreEqual(true, loginVM.LogUserIn("aHashedPassword"));
}
But this gives me an ArgumentException.
I've spent a lot of time trying different ways to make this work and have also tried Rhino Mocks but couldn't get my head around how to mock this call. Can anyone help with this? I haven't tried Moq but suspected it to be similar to Rhino Mocks.
In your current setup this what you're trying to do is impossible. Few things to fix:
start using stable version of Rhino (like 3.6). Better yet, upgrade to Moq which is a newer framework
make GoToMainMenu method virtual (and at least protected)
Your test then (Rhino 3.6) should look like this:
var mock = MockRepository.GenerateMock<LoginViewModel>();
Assert.AreEqual(true, mock.LogUserIn("aHashedPassword"));
Few things to note here. Any non-virtual method called will use your original implementation (like LogUserIn). Every virtual method on the other hand will be replaced by RhinoMocks with default (do nothing) implementation, which should be enough to make test pass. The same test in Moq:
var mock = new Mock<LoginViewModel>();
Assert.AreEqual(true, mock.Object.LogUserIn("aHashedPassword"));
The way it works like this (need to have virtual methods) is because when creating a mock, both Rhino and Moq will generate in memory assembly and create new type there, deriving from your type (in your case, LoginViewModel). Derived type (mock) can then replace any method of original type given it's virtual (standard C# mechanism) or type is interface - then the mock simply implements the interface.
Here is my code below. I am using the Moq library. Instead of letting Moq create an instance for me. I need to flat into a type to pass to someone to create instance later. How do I do that?
var mock = new Mock<IFoo>();
mock.Setup(foo => foo.Bar()).Returns(true);
// Test the actual method
DoSomething(mockedIStateProvider.Object.GetType());
// Not my code, it's a 3rd party library, not allowed to change
public void DoSomething(Type type)
{
Activator.CreateInstance(type);
...
...
}
You can't with Moq. The Activator will always create a new instance which you won't have access to so you won't be able to setup the mocking behaviour you want.
That being said, you can probably get the behaviour you want by writing your own stub implementation that will always do what you want.
I have an interface with a number of generic methods. These methods perform operations based on the type of data that is passed in. How do I mock this with NSubstitute? At the moment, I had to resort to using a concrete class instead of a mock since I cannot handle all possible types that the method will be called with.
public interface IInstanceSource
{
bool CanCreate<T>();
T Create<T>();
void Register<T>(Func<T> creator);
}
public static IInstanceSource GetInstanceSource()
{
var _data = new Dictionary<Type, Func<object>>();
var a = Substitute.For<IInstanceSource>();
//code below fails since T is not defined. How do I make the code below accept any type?
a.WhenForAnyArgs(x=>x.Register(Arg.Any<Func<T>>)).Do(x=> { /* todo */});
a.CanCreate<T>().Returns(x => _data[typeof (T)]);
return a;
}
thanks.
NSubstitute doesn't support setting up multiple instances of a generic method automatically.
The way we'd normally see IInstanceSource used in a test is to configure it for a specific bit of code under test, so T would be known. If a single fixture needed to work for a few different Ts, we could make configuration simpler by having a helper method like ConfigureInstanceSource<T>() which would do the configurations steps for a specific T.
In your case though it seems like you want a fixed behaviour for all fake instances of IInstanceSource, in which case I believe you are going the right way about it by hand-coding your own test double.
I use RhinoMocks for a very simple test (I have to say I'm a beginner here). I tried to mock my object like this
var mock = MockRepository.GenerateMock<MyClass>();
create a helper stub :
var stubLinkedObject = MockRepository.GenerateStub<MyClass>();
then execute some logic which should call the method AddLink of the class MyClass with my stub argument. At the end of the test I simply assert that this method was actually called with
mockAction.AssertWasCalled(a => a.AddLink(stubLinkedObject));
I injected the correct dependency and the method is actually called. However, the problem is that the real implementation in MyClass is called and results in crash because some logic just can't be executed (link collection is not available etc.). How can I bypass the execution and simply check whether a method is called ? I have tried something like
mockAction.Stub(a => a.AddLink(null)).IgnoreArguments().Do(null);
before I go into the execution but this doesn't seem to work(I only get some exceptions). Any ideas and probably an explanation why the mock is executing the method logic at all ?
I've tried to reproduce. Here is the code which works fine for me
[Test]
public void Test()
{
var classMock = MockRepository.GenerateMock<MyClass>();
var linkedMock = MockRepository.GenerateStub<MyClass>();
classMock.Expect(c => c.MyMethod(linkedMock));
classMock.MyMethod(linkedMock);
classMock.AssertWasCalled(c => c.MyMethod(linkedMock));
}
public class MyClass
{
public virtual void MyMethod(MyClass linkedClass)
{
Console.WriteLine("MyMethod is called");
}
}
Your approach will only work if your method AddLink is virtual, otherwise the .Net runtime will always run the real implementation (and rightly so).
Usually the best practise is to use interfaces when doing dependency injection (so your class expects IMyClass instead of MyClass). This way it is much easier to use mocking frameworks - not only you don't have to remember to make all methods virtual, but you avoid the issues with passing correct arguments to MyClass's constructor (which in real world is a pain)