Is it ok to mock parts of the class I am testing? - c#

I am currently writing unit tests for a class that formats values based on parameters found in a big xml file.
The class I am testing receives another class in its constructor that provides functionality to parse and read the xml files. I think it is bad style to give the tested class a concrete instance of the xml reading class, because I believe doing so would result in testing the xml reading class every time I want to - in fact - test the formatting functions of the main class. All unit tests in the formatting class would fail if there was a problem in the xml reading class, which is clearly not the formatting class' fault.
So how should I proceed?
Obviously I would just create a mock of the xml reading class and pass that as an argument to the constructor. However the formatting class would use this instance to create about 5 private instances of other classes.
Because I don't know what these classes want to do (and honestly these tests should not care) I would like to mock away these private fields of the class I am testing.
Is that even ok to do? How would I do that using Moq?
-edit-
see the following example:
public class FormatterCore : IFormatterInterfaceIWantToTest
{
public FormatterCore(IConfigService service)
{
this.something = new SomeStuffA(service);
this.somethingThatINeed = new SomethingUserfull(service);
this.somethingElse = new SomeOtherStuff(service);
this.somethingTotallyDifferent = new SomeReallyUselessStuff(service);
//...
}
public T Format<T>(object input, string id)
{
// implementation of the interface I want to test
}
}
In my example I want to test the method Format<T>() of the interface. To create an instance of the Formatter class, I'd need to pass an instance of a IConfigService implementation (which is expensive and cumbersome, because it would require different xml files and takes a while). My problem here is that I don't want to create an instance of the configService for every unit test because this would mean that I'd test the configService itself with every test in the FormatterCore unit.

In order to test FormatterCore you should not create an instance of a IConfigService implementation. You have to create and set up a mock object of IConfigService.
[TestClass]
public class FormatterCoreTest
{
Mock<IConfigService> сonfigServiceMock;
[TestInitialize]
public void Init()
{
сonfigServiceMock = new Mock<IConfigService>();
}
[TestMethod]
public void Format()
{
// arrange
var input = /* input value */;
var id = /* id value */;
var сonfigServiceMock
.Setup(services => services.YourMethodToMock())
.Returnes(/* expected result or behaviour */);
// act
var target = new FormatterCore(сonfigServiceMock.Object);
var result = target.Format</* AnyType */>(input, id);
// assert
/* Your asserts */
result.Should().Be(/* expectred result */);
Assert.AreEqual /* expectred result */, result);
}
}
Are types SomeStuffA, SomethingUserfull, SomeOtherStuff and SomeReallyUselessStuff nested and can't be tested or public and it is possible?
If it is possible to test types SomeStuffA, SomethingUserfull, SomeOtherStuff and SomeReallyUselessStuff then it is better to inject their instances into constructor of FormatterCore instead of creating them in the constructor.
public class FormatterCore : IFormatterInterfaceIWantToTest
{
ISomeStuffA something;
ISomethingUserfull somethingThatINeed;
ISomeOtherStuff somethingElse;
ISomeReallyUselessStuff somethingTotallyDifferent;
public FormatterCore(
ISomeStuffA someStuffA,
ISomethingUserfull somethingUserfull,
ISomeOtherStuff someOtherStuff,
ISomeReallyUselessStuff someReallyUselessStuff
)
{
this.something = someStuffA;
this.somethingThatINeed = somethingUserfull;
this.somethingElse = someOtherStuff;
this.somethingTotallyDifferent = someReallyUselessStuff;
//...
}
public T Format<T>(object input, string id)
{
// implementation of the interface I want to test
}
}
Let your IoC be responsible for instance creation.
It will be needed to create and setup mocks for all dependencies in every test.

As you can't access the private variables of the XML formatting class (other than hacking into the class by reflection), and you can't be certain of when the other classes are created, I don't think you can mock them in the way you'd like to. Having to hack into a class to access private variables or methods for testing is a code smell - it means you have hidden testable functionality that should be exposed.
So, to expose that functionality, it seems like your best course of action would be to inject factories that the XML formatting class uses to create these other classes. Your XML reader/parser mock would be passed to the Create methods, and you would return appropriate mocks of those classes for the XML formatting class to use.
Alternatively, you could treat the XML formatting class as you would in an integration test - accept that other classes will be created with your XML reader/parser mock as a parameter, and set up that mock to expect calls from them as well.

Related

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());
}
}

Mock set an attribute that doesn't have a set

Hi everyone smarter than me :-) I have another application which requires generation of an abstract class, and due to testing purposes is quite difficult to debug. therefor i created a wrapper and can define my abstract classes in visual Studio now (instead of native application)
However, the native application is expecting public abstract [obj type] values with only a get; method, and if i put in a set;, the application will bomb. Is there any way to set a field using Reflection or Mock to this field, and NOT have the set method?
//simplified class
public abstract class GetEUserAndDetails : [app specific interfaces]
{
public abstract Metastorm.Runtime.Types.Text paramFullNameLike
{
get;
set; //note: If i have this here, it will fail in Metastorm
}
public System.Data.DataSet Read()
{
//do something
}
}
and in Main() it's a c# winform, i have
Mock<Metastorm.Runtime.Models.MySampleProject.GetEUserAndDetails> mockMyBO = new Mock<Metastorm.Runtime.Models.MySampleProject.GetEUserAndDetails>() { CallBase = true };
//using reflection
foreach (PropertyInfo pi in mockMyBO.Object.GetType().GetProperties())
{
//simplified again, another form getting parameters and such
pi.SetValue(mockMyBO.Object, form.myTextParam, null);
}
If I don't have the set method, the pi.SetValue() line will fail, but if i do, it will fail in the native app. (note: i'm using the same test harness to test all sorts of abstract classes that will all implement the Read() method and need to test that it is pulling the correct data back, but the parameters will be different for each class.
Sorry if my code is bad i couldn't get it to format properly, and also please bear with me if i used the wrong terms. I'm not an expert by any means, just enough to be dangerous. I am just living with leaving the set; line for the moment and manually removing it before copy/pasting into the main application, but would like to find another way to do this for when there are many params.
If I understood your scenario correctly, you actually want to test the code in the abstract class, and not mock it.
With that in mind, I think the easiest approach in this case is simply to create a subclass within your test, that will inherit from your base class, and implement whatever is necessary for you to be able to test the base class.
Such as:
public class GetUserAndDetailsImplementation : GetEUserAndDetails
{
private Metastorm.Runtime.Types.Text _paramFullNameLike;
public override Metastorm.Runtime.Types.Text paramFullNameLike
{
get { return _paramFullNameLike; }
}
public void SetParamFullNameLike(Metastorm.Runtime.Types.Text text)
{
_paramFullNameLike = text;
}
}
And you can use that class as entry point for your testing.
Now if you really want to use a mock, have you tried the following?
var mock = new Mock<GetEUserAndDetails> { CallBase = true };
mock.SetupGet(x => x.paramFullNameLike).Returns(<some value>);

NUnit Assert.IsInstanceOf<T> - no way to ensure not a derived class?

I have two classes: Foo and FooBar. FooBar derives from Foo. I have a factory class that, given parameters, decides which object to instantiate and return.
So I want to have unit tests that verify my factory class is working properly and returning the proper instances.
This is somewhat clean for FooBar:
[Test]
public void FooBarFactoryTest()
{
var testObj = FooFactory(paramsForFooBarOnly);
Assert.IsInstanceOf<FooBar>(testObj);
}
But for Foo, it's rather messy:
[Test]
public void FooFactoryTest()
{
var testObj = FooFactory(paramsForFooOnly);
Assert.IsInstanceOf<Foo>(testObj); //An instance of FooBar would pass this assert
Assert.IsNotInstanceOf<FooBar>(testObj); //Can't have just this assert.
}
Is there any way I can re-write this second test to follow the paradigm of "One assert per test?" Preferably, I'd also like to have tests that account for potential additional derivations of Foo or FooBar.
Sure, just use Assert.IsTrue:
Assert.IsTrue(testObj.GetType() == typeof(Foo));
Don't feel like you have to choose only from the various "helper" methods from NUnit.

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.

NUnit Mocking not working for Singleton Method

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.

Categories