In order to properly unit test some of my classes I need to mock the class objects being used by the main class being tested. This is a simple process if all the objects being used implements the interface and I only need to use the methods form that interface. However, and here is the problem:
Interfaces are a contract on what other developers should expect in that class. Therefore all interface methods, properties etc. are public. Any good code should also have good encapsulation. Therefore I don't want to make all methods in my class public and hence don't declare it in the interface. And as a result I can not mock and setup these internal method that is used in my main class.
Other options I looked into was using an abstract class that can have different access modifiers and I can have the correct methods in it be internal or private etc. But since I want the class being mocked to be available is a public property of interface type for other developers to use, I need it be an interface, but now its not compatible anymore since my main class cant call the internal method anymore as its defined as an interface. Catch 22. (In case you were wondering, using virtual for methods will have the same problem as using an abstract class).
I have searched for similar questions regarding C# mocking and did not find the same problem I have. And please don't be philosophical on "C# isn't good language for testing" or such stuff. That's not an answer.
Any ideas?
I added this code example to make it easier to see the problem described above.
[assembly: InternalsVisibleTo("MyService.Tests")]
public interface IMyService
{
MethodABC()
...
}
public class MyService : IMyService
{
public void MethodABC()
{
...
}
internal void Initialize()
{
...
}
...
}
public sealed partial class MyMain
{
public IMyService Service { get; private set; }
private MyService _service;
...
private void SomeMethod()
{
// This method is in interface and can be used outside the project when this assembly is referenced
_service.MethodABC()
...
// This method is and internal method inside the class not to be seen or used outside the project.
// 1) When running this method through unit test that mocked the IMyService will fail here since initialize don't exist which is correct.
// 2) Mocking the MyService will require "virtual" to be added to all methods used and don't provide a interface/template for a developers if
// they want to swap the service out.
// 3) Changing the interface to abstract class and mocking that allows for making this an internal method and also set it up in mock to do
// something for unit test and provides contract other developers can implement and pass in to use a different service, but requires
// "override" for all methods to be used from "outside" this assembly. This is best solution but require changes to code for sole purpose
// of testing which is an anti-pattern.
_service.Initialize()
...
}
}
// Unit test method in test project
[TestClass]
public class MyMainTests
{
private Mock<IMyService> _myServiceMock = new Mock<IMyService>();
[TestMethod]
public void MyMain_Test_SomeMethod()
{
...
SomeMethod()
...
}
}
Interface testing doesn't make sense. Interface doesn't say anything about "what it should do". When I need test something with interface, I make MockClass in my NUnit testing class. This class works only for few tests, and it is internal. If you have same namespaces for your tested class and your tests, there should be internal enough. So it is not public. But still you cannot test any private methods.
Sometimes it is annoying, but I cannot have nice code in my tests. But it is not strange.
I get the point of testing only public methods and properties but sometimes this limitation just makes no sense as well as using interfaces just to support unit tests.
My workaround is to inherit the class I am testing, add public access methods and then call protected base class members from it.
One option to consider is to specify the internal actions on an internal interface that you can then use to mock those actions. Given your example, you could add:
internal interface IInitialize
{
void Initialize();
}
And then implement this in your class alongside your public interface:
public class MyService : IMyService, IInitialize
And then your consuming class can use the interface as needed:
public sealed partial class MyMain
{
public MyMain(IMyService myService)
{
Service = myService;
}
public IMyService Service { get; }
public void SomeMethod()
{
(Service as IInitialize)?.Initialize();
Service.MethodABC();
}
}
Now in the unit test you can utilize the As<TInterface>() method in Moq to handle the multiple interfaces (read the docs):
[Fact]
public void Test1()
{
Mock<IMyService> myServiceMock = new Mock<IMyService>();
Mock<IInitialize> myServiceInitializeMock = myServiceMock.As<IInitialize>();
//myServiceMock.Setup(s => s.MethodABC()).Whatever
//myServiceInitializeMock.Setup(s => s.Initialize()).Whatever
MyMain myMain = new MyMain(myServiceMock.Object);
myMain.SomeMethod();
myServiceMock.Verify(s => s.MethodABC(), Times.Once);
myServiceInitializeMock.Verify(s => s.Initialize(), Times.Once);
}
Note the following remark on As<TInterface>():
This method can only be called before the first use of the mock
Moq.Mock`1.Object property, at which point the runtime type has
already been generated and no more interfaces can be added to it.
Also note that the use of As<TInterface>() also requires the following attribute to allow the mock proxy access to implement the internal interface:
[assembly:InternalsVisibleTo("DynamicProxyGenAssembly2")]
Unfortunately there don't seem to be a clean way of doing this. In order to create a mock using Moq, it needs to be either an interface, abstract class or virtual methods.
Interfaces cant have encapsulation lower than public. Using a internal interface will still force you to create "Public" methods.
Virtual methods allow access modifiers but do not provide an injectable object with a contract to be used by Moq other developers using the main class.
The ideal solution would not require code changes just for the purpose of making it unit testable. This unfortunately don't seem to be possible.
Which brings me to an abstract class that can provide a template (semi interface) that can be handled like an interface but will require "override" for all contract methods but at least will allow correct access modifiers for methods.
This still goes against clean code as I will need to add code to all my methods for the sole purpose of making it unit testable.
This is something Microsoft can look into for new .Net C# features. I will check if they have a feature request for this already.
Related
With Intellitest you can specify a type for Intellitest to use that fits an interface when generating unit tests, however I have a custom factory I wish to use instead.
My custom factory:
public static partial class LogicFactory
{
/// <summary>A factory for ILogic instances</summary>
[PexFactoryMethod(typeof(ILogic))]
public static ILogic Create(string defaultUICulture, bool saveSuccessful)
{
return Mock.Of<ILogic>(
x =>
x.GetUICulture(It.IsAny<string>()) == defaultUICulture &&
x.Save(It.IsAny<string>(), It.IsAny<string>()) == saveSuccessful);
}
}
I would like to use this factory for all ILogic instances PEX tries to create.
I tried adding the following attribute to PexAssemblyInfo.cs, and I also tried adding it above my test:
[assembly: PexCreatableByClassFactory(typeof(ILogic), typeof(LogicFactory))]
but I still get this runtime warning when instrumenting code:
will use Company.Logics.SpecificLogic as ILogic
And so it seems it's ignoring my factory every time. How can I force Intellitest to use my factory instead?
If you want to use PexCreatableByClassFactory you need a class that implements IPexClassFactory interface. Here is an example:
public partial class LogicFactory : IPexClassFactory<Logic>
{
public Logic Create()
{
//...
}
}
[assembly: PexCreatableByClassFactory(typeof(Logic), typeof(LogicFactory))]
It should be noted that IPexClassFactory works with concrete classes and not with interfaces. Now if Pex decides that an instance of Logic class should be created, the following code will be generated:
LogicFactory2 s2 = new LogicFactory();
Logic s1 = ((IPexClassFactory<Logic>)s2).Create();
If you prefer to use PexFactoryMethod it is also possible. However, PexFactoryMethod also works with concrete classes e.g.:
[PexFactoryMethod(typeof(Logic))]
public static Logic Create(string defaultUICulture, bool saveSuccessful)
{
//...
}
If you use both solutions at the same time i.e. define a pex factory method and a pex factory class for the same type, then according to my experience a pex factory method will have a higher priority.
If you have more than one class that implements ILogic interface you need to defined a pex factory method and/or a pex factory class for each of these classes. Otherwise PEX will try to create instances of these classes on his own.
If you want to get rid of mentioned warning right click it and select Fix from a context menu. Pex will generate the following attribute for you:
[assembly: PexUseType(typeof(SpecificLogic))]
I have a test (code is below) to test that Method1 calls Method2. The exception I'm getting is
The current proxy generator can not intercept the specified method for
the following reason: - Sealed methods can not be intercepted.
The method under test isn't sealed itself. However, it does have a dependency on a sealed class (a third-party class for which I am having trouble creating a wrapper in order to mock it properly - another topic for another question). Either way, at this point I'm not asking FakeItEasy to mock the sealed class. And while debugging my test, when the dependency is called, I can clearly see that a real object is being produced, not a fake.
And yet, given the error message, I feel like it might be related somehow.
Further, I discovered through a random blog post that making the method virtual fixes the problem, allowing the test to pass. I gave it a try and it worked. But I don't get why it fixed it, and regardless, it doesn't make sense for me to keep the method virtual. In my case, the class being tested doesn't have any children of its own, ie; no children to override its methods, so I can't see any reason to make it virtual.
Am I wrong in thinking I have no reason to make the method virtual?
Is FakeItEasy somehow trying to mock that sealed class?
I'm really not sure how to proceed with this test.
My Test
[SetUp]
public void SetUp()
{
// Arrange
_service2 = A.Fake<Service2>(x => x.WithArgumentsForConstructor(
() => new Service2()));
_service1 = A.Fake<Service1>(x => x.WithArgumentsForConstructor(
() => new Service1(_service2)));
}
[Test]
public void when_Method1_executes_it_calls_Method2()
{
// Act
result = _service1.Method1();
// Assert
A.CallTo(() => _service2.Method2())
.WithAnyArguments()
.MustHaveHappened();
}
Related Methods
public class Service1 : IService1
{
private readonly IService2 _service2;
public Service1(IService2 service2)
{
_service2 = service2;
}
public bool Method1()
{
using (var dependency = new MyDependency()) // third party sealed class
{
}
var x = _service2.Method2();
}
}
public class Service2 : IService2
{
public bool Method2() // making this virtual fixes the FakeItEasy exception
{
}
}
While normally applied to the class scope, sealed in this case refers to the inability to override the method in question. Using sealed with a method is only valid if the method is an override - however, methods which are not virtual in the first place cannot be overidden, and are thus themselves implicitly sealed.
What this error refers to is that it cannot accept non-virtual methods, due to the fact that it is creating a class on the fly inherited from your given class to perform these intercepts. At such a level, it can neither determine the difference between a non-vritual and sealed method, nor does it need to - it cannot override, and thus cannot insert the appropriate intercept.
Aravol's answer is great. I urge you to accept it and/or vote it up.
There's another approach, though. Make _service2 a fake IService2.
Then you don't have to change the signature of any methods (interface methods are always overridable/interceptable). In general, it's easier to fake interface interfaces than concrete (or even abstract) classes, and it has the nice effect of actually testing that your collaborating classes can work with interfaces, not necessarily just with particular implementations of the interfaces.
While I'm here, and this part isn't really related to your error, but may help make your code a little clearer, since you're testing Service1, I would not fake it; use an actual Service1 instance. This makes it clear to readers what's actually being tested. Faking the system under test is widely considered to be a code smell.
If you happened to take both these points, your SetUp would look a little more like this:
[SetUp]
public void SetUp()
{
// Arrange
_service2 = A.Fake<IService2>();
_service1 = new Service1(_service2);
}
And your test should pass.
I've just been chasing a nearly identical problem for two days now. Blair Conrad's solution above of faking at the interface level worked for me, and also actually makes sense:
If the class being tested doesn't have a dependency on another class, neither should the test. Therefore you fake the interface, rather than a class that implements the interface.
I have a lot of classes in my business layer that have an interface which must always have the same methods and properties as the public methods and properties of my business class. This is a common scenario, as the interface is needed for dependency injection and mocking while unit testing.
It would be optimal if I could somehow define the interface as the same as the public methods and properties of a class. That way I don't have to copy paste method definitions from my implemented class to my interface all the time. I don't see any logical problem with this, but I know that it's not directly possible to do in C#.
Perhaps someone can come up with a reasonable way to accomplish this?
Here is an example. Here is an interface.
public interface IAccountBusiness
{
Guid GetAccountIdByDomain(string domain);
void CreateAccount(string accountType, string accountName);
}
Here is the implementation:
public class AccountBusiness : IAccountBusiness
{
public Guid GetAccountIdByDomain(string domain)
{
// Implementation
}
public void CreateAccount(string accountType, string accountName)
{
// Implementation
}
}
If I want to add a parameter more in CreateAccount, for example "Email", then I have to add it to both the interface and the business class. In this example it's a minor nuisance but in larger scale projects it's ... well ... still a minor nuisance, but it doesn't have to be.
Resharper's Change Signature refactoring allows you to do that easily:
for our asp.net web application v 4.0, we are in process of defining a class that contains methods that are common across the application. to achieve this there are 2 Suggestions within our team.. one to create a base class, define the methods in that and derive all the other classes from that base class.. the other one is to create a seperate class (not a base class) and instantiate that common class in other classes when required to access the common methods. Please guide me in identifying the best approach..
I'd only go the base class route if there is a real is-a relationship between the base class and the derived classes. One reason is that a class can only inherit from a single base class. I'd use this relationship in a sensible way. Just sharing some helper methods is not a scenario worth blocking this relationship.
If you want to use some helper methods in several classes, composition is the better way as you describe in the 2nd approach. Instead of creating the objects in the classes, you should think about whether you can inject the instances into the classes (see this link for details on dependency injection), e.g.:
public class HelperClass
{
public virtual void HelperMethod()
{
// ...
}
}
public class ClassThatUsesHelper
{
private readonly HelperClass _helper;
public ClassThatUsesHelper(HelperClass helper)
{
_helper = helper;
}
public void DoSomething()
{
_helper.HelperMethod();
}
}
By injecting the helper class you decouple the classes so that you can substitute the helper class by a different implementation that shares the same interface. ClassThatUsesHelper works with any class that is derived from HelperClass (or HelperClass itself of course). So if you need to decorate the helper method or need a special implementation in some cases, this is possible without any problem.
Using composition also enables you to test the helper methods separately.
However, if it is about very basic helper methods, you might also think about having a static class with static helper methods. Please note that you introduce a strong dependency between the classes and that you cannot adjust the implementation easily.
public static class HelperClass
{
public static void HelperMethod()
{
// ...
}
}
public class ClassThatUsesHelper
{
public void DoSomething()
{
HelperClass.HelperMethod();
}
}
Your question is vague, but if you need a method which all objects in your program will need to have access to, that uses their member variables, then I wold recommend creating an abstract class upon which your objects are based.
If you need a means of performing some sort of calculation from anywhere in your code, just create a public static method in a class meant for the purpose. MyMathClass.InterestingFourierTransform(), for example.
If I have interface IFoo, and have several classes that implement it, what is the best/most elegant/cleverest way to test all those classes against the interface?
I'd like to reduce test code duplication, but still 'stay true' to the principles of Unit testing.
What would you consider best practice? I'm using NUnit, but I suppose examples from any Unit testing framework would be valid
If you have classes implement any one interface then they all need to implement the methods in that interface. In order to test these classes you need to create a unit test class for each of the classes.
Lets go with a smarter route instead; if your goal is to avoid code and test code duplication you might want to create an abstract class instead that handles the recurring code.
E.g. you have the following interface:
public interface IFoo {
public void CommonCode();
public void SpecificCode();
}
You might want to create an abstract class:
public abstract class AbstractFoo : IFoo {
public void CommonCode() {
SpecificCode();
}
public abstract void SpecificCode();
}
Testing that is easy; implement the abstract class in the test class either as an inner class:
[TestFixture]
public void TestClass {
private class TestFoo : AbstractFoo {
boolean hasCalledSpecificCode = false;
public void SpecificCode() {
hasCalledSpecificCode = true;
}
}
[Test]
public void testCommonCallsSpecificCode() {
TestFoo fooFighter = new TestFoo();
fooFighter.CommonCode();
Assert.That(fooFighter.hasCalledSpecificCode, Is.True());
}
}
...or let the test class extend the abstract class itself if that fits your fancy.
[TestFixture]
public void TestClass : AbstractFoo {
boolean hasCalledSpecificCode;
public void specificCode() {
hasCalledSpecificCode = true;
}
[Test]
public void testCommonCallsSpecificCode() {
AbstractFoo fooFighter = this;
hasCalledSpecificCode = false;
fooFighter.CommonCode();
Assert.That(fooFighter.hasCalledSpecificCode, Is.True());
}
}
Having an abstract class take care of common code that an interface implies gives a much cleaner code design.
I hope this makes sense to you.
As a side note, this is a common design pattern called the Template Method pattern. In the above example, the template method is the CommonCode method and SpecificCode is called a stub or a hook. The idea is that anyone can extend behavior without the need to know the behind the scenes stuff.
A lot of frameworks rely on this behavioral pattern, e.g. ASP.NET where you have to implement the hooks in a page or a user controls such as the generated Page_Load method which is called by the Load event, the template method calls the hooks behind the scenes. There are a lot more examples of this. Basically anything that you have to implement that is using the words "load", "init", or "render" is called by a template method.
I disagree with Jon Limjap when he says,
It is not a contract on either a.) how the method should be implemented and b.) what that method should be doing exactly (it only guarantees the return type), the two reasons that I glean would be your motive in wanting this kind of test.
There could be many parts of the contract not specified in the return type. A language-agnostic example:
public interface List {
// adds o and returns the list
public List add(Object o);
// removed the first occurrence of o and returns the list
public List remove(Object o);
}
Your unit tests on LinkedList, ArrayList, CircularlyLinkedList, and all the others should test not only that the lists themselves are returned, but also that they have been properly modified.
There was an earlier question on design-by-contract, which can help point you in the right direction on one way of DRYing up these tests.
If you don't want the overhead of contracts, I recommend test rigs, along the lines of what Spoike recommended:
abstract class BaseListTest {
abstract public List newListInstance();
public void testAddToList() {
// do some adding tests
}
public void testRemoveFromList() {
// do some removing tests
}
}
class ArrayListTest < BaseListTest {
List newListInstance() { new ArrayList(); }
public void arrayListSpecificTest1() {
// test something about ArrayLists beyond the List requirements
}
}
I don't think this is best practice.
The simple truth is that an interface is nothing more than a contract that a method is implemented. It is not a contract on either a.) how the method should be implemented and b.) what that method should be doing exactly (it only guarantees the return type), the two reasons that I glean would be your motive in wanting this kind of test.
If you really want to be in control of your method implementation, you have the option of:
Implementing it as a method in an abstract class, and inherit from that. You will still need to inherit it into a concrete class, but you are sure that unless it is explicitly overriden that method will do that correct thing.
In .NET 3.5/C# 3.0, implementing the method as an extension method referencing to the Interface
Example:
public static ReturnType MethodName (this IMyinterface myImplementation, SomeObject someParameter)
{
//method body goes here
}
Any implementation properly referencing to that extension method will emit precisely that extension method so you only need to test it once.
How about a hierarchy of [TestFixture]s classes? Put the common test code in the base test class and inherit it into child test classes..
When testing an interface or base class contract, I prefer to let the test framework automatically take care of finding all of the implementers. This lets you concentrate on the interface under test and be reasonably sure that all implementations will be tested, without having to do a lot of manual implementation.
For xUnit.net, I created a Type Resolver library to search for all implementations of a particular type (the xUnit.net extensions are just a thin wrapper over the Type Resolver functionality, so it can be adapted for use in other frameworks).
In MbUnit, you can use a CombinatorialTest with UsingImplementations attributes on the parameters.
For other frameworks, the base class pattern Spoike mentioned can be useful.
Beyond testing the basics of the interface, you should also test that each individual implementation follows its particular requirements.
I don't use NUnit but I have tested C++ interfaces. I would first test a TestFoo class which is a basic implementation of it to make sure the generic stuff works. Then you just need to test the stuff that is unique to each interface.