Mock an Interface that will be instantiate later? - c#

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.

Related

Verifying if a void method has been called using Moq

I have a class which is responsible for building PPT slides for exporting. To unit test this I have created an interface so it can be mocking using Moq; all great so far. However I run into difficulties when trying to test that my method has been called. It is a void method so at this point I only want to know that the method has been hit.
Here is my interface:
interface IPowerpointExporter
{
void AddSlides(int amount);
void setTitle(string title);
}
And here's my unit test:
[TestMethod]
public void testPPTObject()
{
var mockPPT = new Mock<IPowerpointExporter>();
mockPPT.Setup(m => m.AddSlides(1)).Verifiable();
mockPPT.Object.AddSlides(1);
mockPPT.VerifyAll();
}
However when I come to call AddSlides() I get a GeneratorException. The explanation for this is that my IPowerpointExporter was not accessible. I have a feeling this is because I am trying to call a method on an interface, though I'm unsure since I've got my object at mockPPT.Object.AddSlides(); at this point.
Note that I've also tried the following trying to use an actual object rather than Interface.Object. This also gives the same exception:
[TestMethod]
public void testPPTObject()
{
var mockPPT = new Mock<IPowerpointExporter>();
mockPPT.Setup(m => m.AddSlides(1)).Verifiable();
ExportPowerPoint temp = (ExportPowerPoint)mockPPT.Object;
temp.AddSlides(1);
mockPPT.VerifyAll();
}
Using Moq how can I check that my method has been called? Is what I'm doing above along the right lines?
You're likely getting that exception because your interface is not public, or otherwise visible to the Moq assembly. See this question to resolve that.
If this is just dummy code to help you learn Moq, then read no further.
However, if this an actual test that you think has value, then you have other more fundamental issues. In your first example, you're doing absolutely nothing to test your code! Let's go through it, line by line:
var mockPPT = new Mock<IPowerpointExporter>();
You created a mock of your IPowerpointExporter interface, so far so good.
mockPPT.Setup(m => m.AddSlides(1)).Verifiable();
You told the mock to expect a call to it's AddSlide method, with an argument of 1, and that the method can be verified. No problem so far.
mockPPT.Object.AddSlides(1);
But here's where it goes off the rails. You're just invoking the method on your mock, the same one you just setup above. The Object property is a dummy object, it can only do what it was setup to do and has no ties to your actual implementation!
mockPPT.VerifyAll();
Now you verified that you called all your verifiable methods. All you did in this test was verify that Moq works; your code was never touched.
Let's look at the changed code in your second example now:
ExportPowerPoint temp = (ExportPowerPoint)mockPPT.Object;
temp.AddSlides(1);
That cast will never work. The Object property is just some proxy (a dynamic type actually), generated by Moq that knows nothing about any concrete implementation of the interface it is mocking.
This exception occurs because IPowerpointExporter interface is not accessible to Moq.
You can make your IPowerpointExporter interface public, and test runs perfectly:
public interface IPowerpointExporter
{
void AddSlides(int amount);
void setTitle(string title);
}
....
[TestMethod]
public void testPPTObject()
{
var mockPPT = new Mock<IPowerpointExporter>();
mockPPT.Setup(m => m.AddSlides(1)).Verifiable();
ExportPowerPoint temp = (ExportPowerPoint)mockPPT.Object;
temp.AddSlides(1);
mockPPT.VerifyAll();
}
However, when you need make tests to non-public types, you can use InternalsVisibleTo attribute in your assembly to make types visible to Moq.
[assembly:InternalsVisibleTo("DynamicProxyGenAssembly2")]

How do I mock a method call inside the method I want to test using NUnit?

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.

Mock (Moq) with unity container and generics

I have a Container interface with a generic resolve method which, when implemented, resolves using Unity.
public interface IContainer
{
T Resolve<T>();
}
Currently there is a Mock Container class:
public class MockContainer : IContainer {
public T Resolve<T>()
{
return default(T);
}
}
But I want to use Moq for consistency and do the equivalent:
mockContainer
.Setup(container => container.Resolve<T>())
.Returns(default(T));
But I get 2 compile errors 'T' could not be found
Is the Moq syntax wrong, am I missing a reference or can this just not be done?
Edit
I know that mocking the container is not ideal. I could resolve each class one-by-one in my setup code.
My question is whether there is some Moq syntax to perform the equivalent of my actual container.
You usually can't do this (set up generic methods without specifying a type), but if you only want to return default(T) and don't care if the function is called at all, it's enough to simply create the mock without calling Setup:
var mockZincContainer = new Mock<IContainer>();
// works just fine
mockZincContainer.Object.Resolve<DateTime>(); // returns default(DateTime)
mockZincContainer.Object.Resolve<object>(); // returns default(object)
You can even return mocks instead of default(T) by changing the DefaultValue property of the mock from DefaultValue.Empty to DefaultValue.Mock.
You don't need to derive a mock object from your interface. So get rid of MockContainer.
In your unit test you should at that point know what types you want to test. So at that point, just give it a real type and tell it what to return.
i.e.
//arrange
mockZincContainer
.Setup(container => container.Resolve<ISomeInterface>())
.Returns(new ConcreteClassThatDerivesFromSomeInterface());
var testClass = new ClassToBeTested(mockZincContainer.Object);
//act
testClass.DoYourMethod();
//assert
mockZincContainer.Verify(c => c.Resolve<ISomeInterface>(), Times.Once);
Why would you mock the container? This is more of an integration concern. All of your code should be testable without having a container wire them up. Mocking the container to return a dependency which you are then passing in to consuming classes seems like a big waste of time to me.

Setup result for call to extension method

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.

How can I use Rhino Mocks to mock a MEF export?

With reference to the Managed Extensibility Framework (MEF), I'm trying to work out how to create clean tests with mocks.
I have an exported component which has three private imports. Each imported object (field) needs to be mocked. Given that the CompositionContainer uses fancy reflection tactics to set imported private fields of composable parts, even in unit tests I will need to use the container to set those field values.
How do I tell the container at run time to accept a dynamic object I've created with Rhino Mocks as a valid export so that it can be used to satisfy the imports in the component I'm testing?
My question has been answered here.
Hi Nathan
There's a couple of different options here.
Using a batch, you can call the AddExportedObject method to add a mock instance to the container. AddExportedObject allows you to specify the contract for the instance that you are adding. i.e. batch.AddExportedObject(mockLogger, typeof(ILogger));
You an also create a custom export provider to allow you add mock instances. If you follow this link, here are some utils that I use. http://pastie.org/467842. Within you'll find a FakeExportProvider, along with FakeExportDefinitions. The FakeExportDefinitions take a func for the instance. This means you can pass it an instance, or even directly create a mock.
Here's sample code to illustrate usage.
protected override void Context()
{
MockCache = MockRepository.GenerateStub<ICache>();
var metadata = new Dictionary<string, object> ()
var cacheDefinition = new FakeInstanceExportDefinition(typeof(ICache), MockCache, metadata);
FakeProvider = new FakeExportProvider(f => ((FakeInstanceExportDefinition)f).Instance);
FakeProvider.AddExportDefinitions(cacheDefinition);
CacheExport = FakeProvider.GetExport<ICache>();
}
Now above I am querying the export provider directly. However, our container allows passing in an export provider in it's construction. So you can do this...
var container = new CompositionContainer(null, FakeProvider).
HTH
Glenn

Categories