How to test the behavior of the implementations of interface methods in (abstract) classes without having to copy the tests to each class?
I have (abstract) classes that implement multiple interfaces. I know how each interface should behave, and I define this in test methods so that I don't have to manually repeat these tests for each and every implementation of an interface.
I could create for each interface an abstract class with the tests, and have an abstract method CreateSUT() that creates a new instance of the concrete class. But then I'd have to create a new class with the same CreateSUT() implementation for each interface a class implements, as C# does not support multiple inheritance. Is there a better way to do this?
Also note that I also want to test interfaces implemented in abstract classes that have several non-abstract subclasses, complicating the matter slightly.
This question is not about whether I should unit test my interface implementations. Opinions differ and I've decided to do it because I know how the interface implementations are expected to behave (never returning a null value, returning a read-only collection, etc) and putting these tests together makes it much easier for me to test their implementations, however many there may be.
Well, I didn't understand why you need this, but you can write static helper class with tests for your interface. E.g.
public static class IFooTests
{
public static void ShouldDoSomething(this IFoo foo)
{
// Assert something
}
}
Later for every object that implements IFoo interface you can quickly create test methods:
[Test]
public void ShouldDoSomething()
{
Bar bar = new Bar(); // create and setup your concrete object
bar.ShouldDoSomething(); // call interface test extension
}
You could create a list to hold instances of all concrete implementations of your interface, then go through each element in that list and assert the invariant in your test.
Depending on your test framework, there should be a way to get actionable feedback when the test fails.
A quick search found me this for nUnit: http://www.nunit.org/index.php?p=testCaseSource&r=2.5.9
You can mock the abstract class with moq or make a interface that implements all your interfaces and then have your abstract class implement your newly created interface then mock the new interface.
Related
I'm new to the moq framework in .net.
From my research online, it seems like there are 2 ways to make use of this framework. Either mock the interface or mock a concrete class. Seems like when mocking concrete class, only virtual method can be mocked. In my case, I just want to mock a couple method of a class which implements an interface.
For example, if we have the following:
public interface Ifoo
{
int Bar();
}
public class Foo : Ifoo
{
public virtual int Bar()
{
return 0;
}
}
public class Client
{
public Client(Ifoo foo)
{
var temp = foo.Bar();
}
}
Now if I need to unit test Client, I need to pass a mocked Ifoo object in the ctor. In this case, should I do:
var mock = new Mock<Ifoo>();
or
var mock = new Mock<Foo>();
Does it make a difference in my case? What's the pros and cons of mocking interface vs mocking class? To me, mocking interface is always a better solution since mocking a class can only give the mock of the virtual method.
Here are some points to consider:
Your client consumes IFoo, so that's what you should mock.
If your client consumes a concrete class, you should think about refactoring your client to consume the interface or abstract class instead to comply with SOLID principles.
If your client consumes a mock of Foo during your test instead of the interface and it relies on some of the non-mocked behavior in that test, you're not really writing a unit test since you're testing the behavior of more than one unit.
If your client doesn't consume any non-mocked behavior during the test then you might as well just pass a mock of the interface anyway.
tldr: Classes should consume interfaces or abstract classes rather than concrete classes. Tests should mock interfaces or abstract classes rather than concrete classes.
I am working on .NET 4.0 using C# in Windows 7.
I want to test the communication between some methods using mock. The only problem is that I want to do it without implementing an interface. Is that possible?
I just read a lot of topics and some tutorials about mock objects, but all of them used to mock interfaces, and not the classes. I tried to use Rhino and Moq frameworks.
Simply mark any method you need to fake as virtual (and not private). Then you will be able to create a fake that can override the method.
If you use new Mock<Type> and you don't have a parameterless constructor then you can pass the parameters as the arguments of the above call as it takes a type of param Objects
Most mocking frameworks (Moq and RhinoMocks included) generate proxy classes as a substitute for your mocked class, and override the virtual methods with behavior that you define. Because of this, you can only mock interfaces, or virtual methods on concrete or abstract classes. Additionally, if you're mocking a concrete class, you almost always need to provide a parameterless constructor so that the mocking framework knows how to instantiate the class.
Why the aversion to creating interfaces in your code?
With MoQ, you can mock concrete classes:
var mocked = new Mock<MyConcreteClass>();
but this allows you to override virtual code (methods and properties).
I think it's better to create an interface for that class. And create a unit test using interface.
If it you don't have access to that class, you can create an adapter for that class.
For example:
public class RealClass
{
int DoSomething(string input)
{
// real implementation here
}
}
public interface IRealClassAdapter
{
int DoSomething(string input);
}
public class RealClassAdapter : IRealClassAdapter
{
readonly RealClass _realClass;
public RealClassAdapter() => _realClass = new RealClass();
int DoSomething(string input) => _realClass.DoSomething(input);
}
This way, you can easily create mock for your class using IRealClassAdapter.
Hope it works.
If you cannot change the class under test, then the only option I can suggest is using MS Fakes https://msdn.microsoft.com/en-us/library/hh549175.aspx.
However, MS Fakes works only in a few editions of Visual Studio.
The standard mocking frameworks are creating proxy classes. This is the reason why they are technically limited to interfaces and virtual methods.
If you want to mock 'normal' methods as well, you need a tool that works with instrumentation instead of proxy generation. E.g. MS Moles and Typemock can do that. But the former has a horrible 'API', and the latter is commercial.
If worse comes to worse, you can create an interface and adapter pair.
You would change all uses of ConcreteClass to use the interface instead, and always pass the adapter instead of the concrete class in production code.
The adapter implements the interface, so the mock can also implement the interface.
It's more scaffolding than just making a method virtual or just adding an interface, but if you don't have access to the source for the concrete class it can get you out of a bind.
It is a bit old question but nevertheless. There are powerful mocking frameworks these days that are capable of mocking concrete classes like JustMock and Typemock.
I faced something like that in one of the old and legacy projects that i worked in that not contains any interfaces or best practice and also it's too hard to enforce them build things again or refactoring the code due to the maturity of the project business, So in my UnitTest project i used to create a Wrapper over the classes that I want to mock and that wrapper implement interface which contains all my needed methods that I want to setup and work with, Now I can mock the wrapper instead of the real class.
For Example:
Service you want to test which not contains virtual methods or implement interface
public class ServiceA{
public void A(){}
public String B(){}
}
Wrapper to moq
public class ServiceAWrapper : IServiceAWrapper{
public void A(){}
public String B(){}
}
The Wrapper Interface
public interface IServiceAWrapper{
void A();
String B();
}
In the unit test you can now mock the wrapper:
public void A_Run_ChangeStateOfX()
{
var moq = new Mock<IServiceAWrapper>();
moq.Setup(...);
}
This might be not the best practice, but if your project rules force you in this way, do it. Also Put all your Wrappers inside your Unit Test project or Helper project specified only for the unit tests in order to not overload the project with unneeded wrappers or adaptors.
Update:
This answer from more than a year but in this year i faced a lot of similar scenarios with different solutions.
For example it's so easy to use Microsoft Fake Framework to create mocks, fakes and stubs and even test private and protected methods without any interfaces.
You can read: https://learn.microsoft.com/en-us/visualstudio/test/isolating-code-under-test-with-microsoft-fakes?view=vs-2017
I started organizing my unit tests in the way Phil Haack suggested here. My test classes have one nested class per public method under test. The nested classes are derived from the outer class in order to inherit its setup code.
I now have a case where I want to test a simple hierarchy of one abstract base class and two derived classes. I would like to test the interactions of each derived class with base class explicitly rather than testing the base class with some kind of mock derived class.
I've done this in the past using a base test fixture and one derived fixture per derived class where the derived fixtures have to implement a few template methods for the tests in the base fixture:
[TestFixture]
public abstract class BaseFixture
{
protected abstract MyBaseClassUnderTest GetTestInstance();
[Test]
public void SomeMethod_SomeCondition_SomeOutcome()
{
var sut = GetTestInstance();
//test base class behavior here
}
//More base class tests here
}
public class DerivedFixture : BaseFixture
{
protected override MyBaseClassUnderTest GetTestInstance()
{
return new DerivedInstance();
}
//Tests for derived class go here
}
Does anybody have an idea, how I can resolve this? Right now I can't see, how I can combine the two approaches, because of the different inheritance strategies (inheriting setup code from the outer class versus inheriting base class tests from base class fixture).
It's a really interesting problem, of course multiple inheritance isn't possible therefore I guess you need to find an alternative to one of the two inheritance strategies you are using.
Personal opinion is that you should keep the Haack method of organizing tests for consistency across the test suite, and look for an alternative to your approach for sharing tests through a class hierarchy. The closest concept I know to multiple inheritance is that of Mixins, and if you look at this answer to Is it Possible to Implement Mixins in C# it appears that mixins can be simulated using extension methods. I would go down this path - this blog post discusses possible strategies for creating mixins that can access data held in the class that uses them, which you would require I believe to be able to supply the derived class instance to your base class level tests (i.e. replacing GetTestInstance).
I can understand why to program against an interface rather than an implementation. However, in an example like the following (I find this a lot):
public interface ISomething
{
void BlahOne(int foo);
void BlahTwo(string foo);
}
public class BaseSomething : ISomething
{
public void BlahOne(int foo)
{
//impl
}
public void BlahTwo(string foo)
{
//impl
}
}
public class SpecificSomethingOne : BaseSomething
{
public void SpecificOne()
{
//blah
}
}
public class SpecificSomethingTwo : BaseSomething
//and on..
The current example of this is the component based entity system in my game. (I have IComponent, Component, PosComponent, etc).
However, I cannot see a reason to have ISomething. The name may look nicer, but it doesn't seem to have a purpose. I can just return BaseSomething all the time.
Is there a reason to have an interface when you have a single base implementation everything uses? (I can see the use for, say, IComparable or IEnumerable)
EDIT: For a slightly different scenario (yet still related enough to not need a different question), if I assume I have this structure for everything, would there be much difference if I were to use ISomething for parameter types and variables compared to BaseSomething?
I prefer "lazy design" - extract the interface from BaseSomething when you need it. Until then, keep it simple and skip it.
Right now I can think of two reasons for having an interface when there is only one implementation:
There is another mock implementation for unit tests (i.e. there is a second implementation, although not in production code).
The interface and the implementation are defined in different class libraries. E.g. when using the Model-View-Presenter pattern, the view can reside in an .exe project that is dependent on the .dll where the presenter is implemented. Then an IView interface can be put in the .dll and the presenter's reference to the view supplied through dependency injection.
Correct answer to your question would be "It depends".
You can look at it in many different ways and it's all about perspective. When you have a concrete or abstract base class, it means your objects have something in common functionally. And derived objects are inter-related in some way or the other. Interfaces let you confirm to a functional contract only where each object implementing the interface will be responsible for the implementation.
Again, when you program again interfaces, you strictly know the capabilities of the object since it implements the given interface. And you need not worry about how each object functionally implements this.
It'd not be completely wrong, If I say
each of your objects are completely
independent when it comes to
implementing the interface ISomething, given that SpecificSomethingOne and SpecificSomethingTwo do not derive from BaseSomeThing and each implement their own ISomething.
You can refer to this answer on the same matter.
it is not really necessary but it is a better design if you want to extend your program later or you want to implement another Base-Class.
In your case I would not implement the Base-Class. The Interface only is just fine if you dont want to have a default-behaviour. If you want a default-behaviour then just write the Base-Class without an Interface
If your BaseSomething were abstract and you had implementing specific things that provider overloads to abstract methods, the only way to program to them at that point would be to the ISomething interface. However, in the example you showed, there is really no reason for ISomething unless you could have multiple base implementations.
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.