NUnit Mocking not working for Singleton Method - c#

Bear with me, I'm new to NUnit. I come from the land of Rails, so some of this is new to me.
I have a line of code that looks like this:
var code = WebSiteConfiguration.Instance.getCodeByCodeNameAndType("CATALOG_Brands_MinQty", item.Catalog);
I'm trying to mock it, like this (assume code is already initialized):
var _websiteConfigurationMock = new DynamicMock(typeof(WebSiteConfiguration));
_websiteConfigurationMock.ExpectAndReturn("getCodeByCodeNameAndType", code);
When I debug the test, getCodeByCodeNameAndType is returning null, instead of the expected code. What am I doing wrong?
NUnit version: 2.2.8

I'm sorry, but I've never used NUnit.Mocks - but I do have some experience with NMock and Moq [which, by the way, I highly recommend]. Typically, you use a mocking library to generate proxies for Interface definitions, and I presume NUnit.Mocks operates the same way.
Therefore, if you would like to mock your singleton, you will likely have to do the following,
a. Create an interface, say
// All methods you would like to mock from this class, should
// be members of this interface
public interface IWebSiteConfiguration
{
// Should match signature of method you are mocking
CodeType getCodeByCodeNameAndType (
string codeString,
CatalogType catalogType);
}
b. "Implement" interface
// You've already written the method, interface matches signature,
// should be as easy as slapping interface on class declaration
public class WebSiteConfiguration : IWebSiteConfiguration { }
c. Consume interface
alright, so step c. is where most of your work will be. Logically, if you are mocking your singleton, you are actually unit testing the consumer [which you have left out of your sample]. For c. simply add a parameter to the consumer's ctor, or add a publicly accessible property of Type 'IWebSiteConfiguration', and then internally, reference the instance member and invoke your methods against this new interface. Consider this,
was
public class MyClass
{
public MyClass () { }
public void DoSomething ()
{
// bad singleton! bad boy! static references are bad! you
// can't change them! convenient but bad!
code = WebSiteConfiguration.Instance.getCodeByCodeNameAndType (
"some.string",
someCatalog)
}
}
becomes
public class MyClass
{
private readonly IWebSiteConfiguration _config = null;
// just so you don't break any other code, you can default
// to your static singleton on a default ctor
public MyClass () : this (WebSiteConfiguration.Instance) { }
// new constructor permits you to swap in any implementation
// including your mock!
public MyClass (IWebSiteConfiguration config)
{
_config = config;
}
public void DoSomething ()
{
// huzzah!
code = _config.getCodeByCodeNameAndType ("some.string", someCatalog)
}
}
In your unit test, create the mock, pass a reference of the mock to the consumer, and test the consumer.
[Test]
public void Test ()
{
IWebSiteConfiguration mockConfig = null;
// setup mock instance and expectation via
// NUnit.Mocks, NMock, or Moq
MyClass myClass = new MyClass (mockConfig);
myClass.DoSomething ();
// verify results
}
This also serves as a practical introduction to Dependency Injection [DI]. It's simply the practice of passing, or "injecting", references of services [eg your web site configuration class] to the consumer, rather than having the consumer invoke the service directly [eg via static singleton class].
Hope this helps :)

A DynamicMock creates a new object in-memory that represents the interface, or marshallable (inherits from MarshalByRef) class you want to mock.
Try this:
var _websiteConfigurationMock = new DynamicMock(typeof(WebSiteConfiguration));
_websiteConfigurationMock.ExpectAndReturn("getCodeByCodeNameAndType", code);
WebSiteConfiguration conf = (WebSiteConfiguration)_websiteConfigurationMock.MockInstance;
var x = conf.getCodeByCodeNameAndType("CATALOG_Brands_MinQty", item.Catalog);
Note that the third line there will not work unless WebSiteConfiguration inherits from MarshalByRef.
What you typically do is mock an interface and get a new object that implements this interface, but behaves the way you've configured it to do, without having to go and make a concrete type for it, so I'm not entirely sure what you're doing is going to work unless you employ a better isolation framework, like TypeMock that can intercept calls to static methods/properties in existing objects.

Seems there is a kind of solution for this using reflection, or maybe I totally misunderstood this.
It is discussed here:
http://www.geekbeing.com/2010/05/23/how-to-unit-test-singleton-hack-in-c
Could it really works?
public class TestableSingleton : SingletonClass
{
public TestableSingleton ()
{
FieldInfo fieldInfo = typeof(SingletonClass)
.GetField("_instance",
BindingFlags.Static | BindingFlags.NonPublic);
fieldInfo.SetValue(Instance, this);
}
}
Project availabe on https://github.com/rbabreu/TestableSingleton
Actually I could not compile it on Visual Studio since the SingletonClass would have a private constructor. If someone get it to work would be great to avoid the overhead of adapter pattern.

Related

Unable to return an interface in mocked method when it should be a internal sealed class

We are creating unit tests in XUnit for one of our projects our ASP.NET application. In the project, we are trying to mock out a particular third party client we don't have access to the source code and does not provide an interface (just a client object we can create). To fix this, we wrote a wrapper class and an interface to that class so we can mock out the functionality we need for that client. This part is all good.
One of the methods we created in the wrapper class and interface was a GetInnerChannel method to get a property from the client (which we want to mock out). However, that method returns an Interface of IClientChannel from System.ServiceModel.
public IClientChannel GetInnerChannel()
{
return client.InnerChannel;
}
It seems harmless, but, in our mock setup, we are unable to create a fake IClientChannel object that is useful for the method we are testing. Here is our unit test code for clarification:
client.Setup(i => i.GetInnerChannel()).Returns(GetClientChannel());
In the Returns call, you will see we are returning a method return which we currently set to null for now. This is because we cannot instantiate an interface. When I dived into debugging, I found that the object that is being sent back in place of the interface during normal operation is a System.Runtime.Remoting.Proxies.__TransparentProxy object. A little investigation into the __TransparentProxy class is that it is an internal sealed class (which means we cannot instantiate that in our unit test code).
Unfortunately, the method we are testing is using the InnerChannel in this way:
public List<EquifaxQuestion> GetEquifaxQuestions(User basicUserInfo, IEnumerable<AddressViewModel> Addresses)
{
try
{
InitialResponse response;
using (new OperationContextScope(client.GetInnerChannel()))
{
OperationContext.Current.OutgoingMessageHeaders.Add(
new EquifaxSecurityHeader(appID, username, password));
response = client.SubmitInitialInteraction(GenerateInitialRequest(basicUserInfo, Addresses));
}
Which I don't if we can replace the GetInnerChannel call and thus we require a mock of it to just get through the unit test since we must mock out our client.
Is there another way I can return a value or object that is useful for GetInnerChannel()? Am I missing a step in my mock setups? Or is Moq and other mocking frameworks incapable to do what I need to do? Or is the method I am trying unit test against unable to be unit tested? Thank you in advance.
Basically the solution for this was a lot of wrappers and interfaces to work in WCF. It is quite lengthy, but this blog post does a better job. https://weblogs.asp.net/cibrax/unit-tests-for-wcf
In short, if you have static, sealed, or other third party class you can't mock, wrap it in a simple task with all public methods written in them with them calling your third party class's method and then create an interface for the wrapper. In your unit tests, use the interface and in your normal code, use your wrapper class.
This is possible without having to write any more wrappers. It is important to understand the principle of indirection that gets introduced by adding an interface. Every interface added is an opportunity to isolate the abstraction and make it look and feel different.
I have attached the important snippets below, due to expected brevity I am not attaching entire solution.
Quick explaination of classes and usage hierarchy -
1. IInnerChannel is the interface exposed by the third party library.
2. IClientChannelWrapper is the wrapper class created in order to hide inner interface from calling clients.
3. ClassUsingChannelWrapper is the class that invokes this logic and in our unit test its method is going to be our sut (subject under test).
Code goes as below -
The IInnerChannel interface declaration-
public interface IInnerChannel
{
string TheInnerChannelMethod();
}
The InnerChannel implementation (probably in the third party library in your case)-
public class InnerChannelImplementation : IInnerChannel
{
public InnerChannelImplementation()
{
}
public string TheInnerChannelMethod()
{
var result = "This is coming from innser channel.";
Console.WriteLine(result);
return result;
}
}
The wrapper created by you around the inner channel -
public interface IClientChannelWrapper
{
void DoSomething();
IInnerChannel GetTheInnerChannelMethod();
}
The wrapper interface's implementation -
public class ClientChannelWrapperImplementation : IClientChannelWrapper
{
public ClientChannelWrapperImplementation()
{
}
public void DoSomething()
{
Console.WriteLine("The DoSomething Method!");
}
public IInnerChannel GetTheInnerChannelMethod()
{
InnerChannelImplementation imp = new InnerChannelImplementation();
return imp;
}
}
The class that calls your wrapper's implementation. This class is going to be your SUT when implementing unit tests -
public class ClassUsingChannelWrapper
{
IClientChannelWrapper _wrapper;
public ClassUsingChannelWrapper(IClientChannelWrapper wrapper)
{
_wrapper = wrapper;
}
public void TheClientChannelConsumerMethod()
{
IInnerChannel theChannel = _wrapper.GetTheInnerChannelMethod();
var result = theChannel.TheInnerChannelMethod();
Console.WriteLine(result);
}
}
Finally, the unit test with mocks mimicking behaviour of both interfaces. Notice how mocked client channel wrapper is returning mocked internal channel object which returns pre-programmed value.
public class UnitTest1
{
[Fact]
public void Test1()
{
//Arrange
Mock<IInnerChannel> innerChannelMock = new Mock<IInnerChannel>();
innerChannelMock.Setup(i => i.TheInnerChannelMethod()).Returns("This
is a test from mocked object.");
Mock<InterfaceUt.IClientChannelWrapper> mockClientWrapper = new
Mock<IClientChannelWrapper>();
mockClientWrapper.Setup(m =>
m.GetTheInnerChannelMethod()).Returns(innerChannelMock.Object);
//Act
ClassUsingChannelWrapper sut = new
ClassUsingChannelWrapper(mockClientWrapper.Object);
sut.TheClientChannelConsumerMethod();
//Assert
innerChannelMock.Verify();
mockClientWrapper.Verify();
}
}
Running this unit test prints
"This is a test from mocked object."
Essentially, your unit test is targeting only the client code that attempts to use your interface behaviour. This does not test the implementation of your wrapper. If you want to achieve that you will have to create a new instance of wrapper class instead of mock object and feed it with inner channel's mock object.

How to mock a MEF ExportFactory<TGeneric> using Moq instances?

How can I mock a Managed Extensibility Framework (MEF) import into an ExportFactory[IMyType[T]], using mocks of IMyType[T] (being itself a generic interface)? Or, in general, specify instances to be returned by the ExportFactory, which can't be created with a constructor alone?
Moq can't create a mock instance directly, as far as I know. I want an alternative to implementing the whole interface, which may be much larger and change, while I don't want to change the test.
I once found a very complex ExportProvider code, with key-value strings, which didn't work if the generic type of the ExportFactory[T] was itself generic.
Edit:
It turned out that the existing code used contract name strings, generated from type.FullName. This was fine for non-generics, but generics have a different name syntax. The code I worked with, already has a quite complex class, derived from ExportProvider and overriding some original methods, which allows Moq mock.Object instances to be returned by the factory. It's actually always the same instance, not really a factory. See also this question on CodeReview: https://codereview.stackexchange.com/questions/208550/retrieve-generic-contract-names-for-managed-extensibility-framework
// actual generic type is meaningless here, but it is a generic interface
public interface IMyType<T>
{
string GetMessage();
}
public class FactoryImporter<T>
{
[Import]
ExportFactory<IMyType<T>> MyTypeFactory {get;set;}
}
public class Tester
{
public void TestFactoryImporter()
{
Func<IMyType<string>> createMockFunc = () =>
{
var mock = new Mock<IMyType<string>>();
mock.Setup(m => m.GetMessage()).Returns("I'm a mocked IMyType<string>");
return mock.Object;
}
var regBuilder = new RegistrationBuilder();
// pseudo-code, how to do this in reality?
regBuilder.ForType<IMyType<string>>().CreateInstance(createMockFunc);
var catalog = new AggregateCatalog();
var appCatalog = new ApplicationCatalog(regBuilder);
catalog.Catalogs.Add(appCatalog);
var container = new CompositionContainer(catalog);
var factoryImporter = new FactoryImporter<string>();
container.ComposeParts(factoryImporter);
Assert.AreEqual(
"I'm a mocked IMyType<string>",
factoryImporter.MyTypeFactory.GetExport().Value.GetMessage());
}
}

How to mock a function call in the method I am testing - currently using NSubsitute

I am new to trying to mock things in unit tests...
Example Code simplified for posting:
namespace MockInvestigate.Monitor
{
internal interface IAgentRepo
{
Dictionary<string, string> GetAgentAppSettings(string moduleName);
}
public class AgentRepo : IAgentRepo
{
public virtual Dictionary<string, string> GetAgentAppSettings(string moduleName)
{
return new Dictionary<string, string> { { "real", "data" } };
}
}
}
This is the method I want to unit test - but override the call to GetAgentAppSettings
namespace MockInvestigate
{
public class Class1
{
public static bool IsInitialized(string taskName)
{
AgentRepo ar = new AgentRepo();
var arReturn = ar.GetAgentAppSettings(taskName);
return arReturn.ContainsKey("real");
}
}
}
The unit test - trying to mock the call to 'GetAgentAppSettings'
[TestMethod]
public void TestMethod1()
{
var repo = Substitute.ForPartsOf<AgentRepo>();
var appReturn = new Dictionary<string, string> { { "bogus", "bogus2" } };
repo.GetAgentAppSettings("somevalue").ReturnsForAnyArgs(appReturn);
bool retValue = Class1.IsInitialized("somevalue");
Assert.IsFalse(retValue);
}
When my test is run, the real GetAgentAppSettings is called, returning "real", "data" and not the bogus data I want.
I have tried .When(...).DoNotCallBase().
Can my test be modified to work? Does the underlying code need to change to work?
Any help would be appreciated.
After creating the substitute repo, you have to inject it inside Class1.
In your code, however, you are creating the AgentRepo inside the IsInitialized method, thus it's not using the substitute you created in the test method.
You have to inject the substitute by constructor injection, property injection or method injection.
As the name suggests, constructor injection is when you inject the dependency from the constructor. Since the method IsInitialized is static, that's not an option.
Likewise, property injection uses properties to inject the dependencies. You could create a static property, usually you'd stay away from it though.
It'd always use the same instance for every thread, hence you'd have to guarantee that the AgentRepo is thread-safe.
As last resort, you can use the method injection. You'd get the AgentRepo instance as a method argument and let the caller be responsible for creating it.
Since this is a small repro, I can't tell you what's the best way to deal with it. What I do know is that the AgentRepo must be injected into Class1 somehow.

NUnit TestFixture with no-arg constructors

How do you get around the scenario where the TestFixture you are trying to define needs to reference types that do not have a no-arg constructor?
I'm trying to test an interface that has multiple implementations. From the NUnit documentation it showed how this could be setup with generics like this (where I can define multiple implementation types):
[TestFixture(typeof(Impl1MyInterface))]
[TestFixture(typeof(Impl2MyInterface))]
[TestFixture(typeof(Impl3MyInterface))]
public class TesterOfIMyInterface<T> where T : IMyInterface, new() {
public IMyInterface _impl;
[SetUp]
public void CreateIMyInterfaceImpl() {
_impl = new T();
}
}
The problem arises because Impl1MyInterface, Impl2MyInterface, etc do not have no-arg constructors so when NUnit tries to discover the available test cases I get this error (and the tests do not show up in VS):
Exception System.ArgumentException, Exception thrown discovering tests
in XYZ.dll
Is there a way to work around this? It doesn't make sense to define no-arg constructors because my code needs those values to work.
Instead of using new T() to instantiate your objects, you could use a dependency injection container to instantiate them for you. Here's an example using Microsoft's Unity:
[SetUp]
public void CreateIMyInterfaceImpl() {
var container = new UnityContainer();
// Register the Types that implement the interfaces needed by
// the Type we're testing.
// Ideally for Unit Tests these should be Test Doubles.
container.RegisterType<IDependencyOne, DependencyOneStub>();
container.RegisterType<IDependencyTwo, DependencyTwoMock>();
// Have Unity create an instance of T for us, using all
// the required dependencies we just registered
_impl = container.Resolve<T>();
}
As #Steve Lillis has said in his answer, you need to stop using new T(). When you do this, you don't need to use the new constraint on your generic. One option would be to use an IOC container, like Castle Windsor / Unity as Steve suggested to resolve the dependencies in your Setup.
You haven't said what parameters your implementation's constructors take, but if they're all the same, then an alternate would be to use Activator.CreateInstance instead. So, if your constructors all took an integer and a string, your code would look like this:
[TestFixture(typeof(Impl1MyInterface))]
[TestFixture(typeof(Impl2MyInterface))]
[TestFixture(typeof(Impl3MyInterface))]
public class TesterOfIMyInterface<T> where T : IMyInterface {
public IMyInterface _impl;
[SetUp]
public void CreateIMyInterfaceImpl() {
int someInt1 = 5;
string someString = "some value";
_impl = (T)Activator.CreateInstance(typeof(T), new object[] { someInt1, someString });
}
}

Moq - mock.Object.MyMethod mocking does not work

I have a strange trouble. I am not too familiar with Moq, being more a GUI guy. I tried to mock a factory method in my code. The factory looks like this, and returns a ISettings instance which does many IO Operations. I want it to return a memory only ISettings instance to accelerate my test.
public class SettingsFactory
{
internal ISettings mSettingsImpl;
internal virtual ISettings CreateOrGetSettings()
{
return mSettingsImpl ?? (mSettingsImpl = new XmlSettings());
}
}
and the mock is
var imocked = new Mock<SettingsFactory>() {CallBase = false};
imocked.Setup(x => x.CreateOrGetSettings()).Returns(new NonPersistingSettings());
var tryToSeeTheType = imocked.Object.CreateOrGetSettings();
the tryToSeeTheType is however XMLSettings and not NonPersistingSettings as I would expect. Stepping through results into the code shown me that it goes directly into the original factory method. Any suggestions what I do wrong here?
The "Object" property of a mocked object is not actually an instance of the class you are trying to mock.
The purpose of a mock is to be able to replace an object the method you are trying to test depends on.
Imagine that your SettingsFactory performs very expensive operations like for example accessing the network or a database or the file system. You do not want your test to access those expensive resources so you create a mock. I would be something like this:
public class ClassThatUsesSettingsFactory
{
private readonly SettingsFactory _settingsFactory;
public ClassThatUsesSettingsFactory(SettingsFactory settingsFactory)
{
_settingsFactory = settingsFactory;
}
public void MethodThatCallsSettingsFactory()
{
//... do something
var settings = _settingsFactory.CreateOrGetSettings();
//... do something
}
}
By doing this you are able to replace the SettingsFactory with a mock on your unit test like so:
[TestMethod]
public void MakeSureSettingsFactoryIsCalled()
{
var settingsFactoryMock = new Mock<SettingsFactory>();
settingsFactoryMock.Setup(f => f.CreateOrGetSettings(), Times.Once).Verifiable();
var subjectUnderTest = new ClassThatUsesSettingsFactory(settingsFactoryMock.Object);
subjectUnderTest.MethodThatCallsSettingsFactory();
settingsFactoryMock.Verify();
}
This unit test is basically only making sure that the method CreateOrGetSettings gets called once and only once when the MethodThatCallsSettingsFactory gets executed.
What Moq does is to create a different class with a different implementation of its virtual method that will, most likely, set a flag to true once it gets called and then check the value of that flag on the "Verify" method.
There is a lot to grasp here so I hope it is clear enough since you mentioned that you do not have a lot of experience with Moq.

Categories