I have Core project which contains e.g. interaface ISomeValidator and in Application project I have implementation of this interface. If I want to test this interface, should I create test named like Core.UnitTests or Application.UnitTests? I don't know because Core contains interface of this class and Application his implementation. And I will use interface, not directly implementation.
The main purpose of unit testing is "quality assurance". We want to ensure that the code is behaving as expected. But if there are interfaces only - which do not have any logic - what would unit tests do then?
Besides that, if the "core" project only contains interfaces I would suggest to reconsider the way how the code is organized. Usually the "core" project would contain the main business logic, the domain model, the rules which are valid/important for all use cases. If this logic is not in the "core" project, what is the purpose of "core" then?
Related
In an attempt to make my code friendly for unit testing, it seems wise to utilize depenency injection. This requires that any dependent class must implement an interface with the exact same set of methods.
I also see advice saying that I shouldn't have an interface for every class, but I don't see how I could possibly follow both pieces of advice. If I want unit testing, every single useful class must adhere to an interface.
Proof: Suppose there exists a class that does not implement any interfaces. If I am able to unit test my entire program, then no other code depends on this class. Therefore this class is useless and might as well be deleted.
Is there something I am misunderstanding? Is there a way to unit test without copy/pasting all of my classes into equivalently structured interfaces?
In order to write effective tests, you do need seams in your code (a place that let's you break your dependencies apart) to allow you to control any dependencies in your code. Interfaces are possibly the most obvious way to do this, but you can use other techniques such as wrapping your dependency in a method on your class under test and declaring that method as protected virtual (c#) and overriding the class for your unit tests. There is a great series of videos on YouTube around TDD that deal with design decisions when doing TDD. Search for "is TDD dead".
When unit testing, you usually just want to mock classes that make external calls (be it a database query or hitting an API). Consequently, you need to have an interface for these classes. However, a lot of times you may have random DTOs or utility classes that do small simple things and don't need to be mocked.
Some languages have tools that let you mock classes without writing a corresponding interface; for instance, Python allows patching arbitrary classes in test code, and the Mockito library for Java can generate a mock object from any class.
There is a school of thought that says when writing unit tests, only the "leaves", i.e. classes and methods which don't invoke other classes within the application, should be unit tested in isolation, and classes that are involved in orchestrating the behavior of other classes should be tested at the acceptance or integration level. This style of testing avoids writing unit tests that depend on mocking most of the classes in your application, and so avoids the need to write interfaces. Martin Fowler's article on mocks covers some of the differences between different styles of testing regarding mocks.
In MVC/MVP style applications that have Controller/Presenter classes within the Client Application assembly and then a Services layer assembly containing Service classes, where do people recommend storing their unit tests?
For ease of execution it'd be nice to have a single Test assembly that references both the Client and Services, and contains tests for both. But is anything about a dual responsibility Test assembly considered bad design?
Where are other people storing their unit test code?
It's pretty important that you keep unit test projects isolated to only one System Under Test (SUT). If required, you can have more than one unit test project that exercises the same SUT, but not the other way around.
The reason for this is that if you have a single unit test project that exercises multiple SUTs, you are artificially coupling those two SUTs together. This means that you will never be able to migrate one of the SUTs without the other.
In the case of a web application, you may find such concerns irrelevant if you don't plan to reuse any of your libraries, but imagine that you are unexpectedly asked to implement a web service based on the same business logic as the web site currently uses. Your service layer sounds like a good candidate for code reuse, so you may want to reuse it without the MVC-based UI.
The problem now is that you can't, because the single unit test project drags along the unwarranted UI project.
Having a one-to-one relationship between SUTs and their unit tests just makes your life a lot easier.
I usually create a unit test project per .NET assembly tested.
I have written my units tests, and where external resources are needed it is dealt with by using fakes.
All is good so far. Now i' am faced with the other test phases, mainly integration where i want to repeat the unit test methods against real external resources e.g The Database.
So, What are the recommendations for structuring test projects for Unit Vs Integration testing? I understand some people prefer separate assemblies for unit and Integration?
How would one share common test code between the two assemblies? Should i create a thrid assembly which contains all the Abstract Test Classes and let the unit and integration inherit? I am looking for maximum re-usability...
I hear alot of noise about Dependency Injection (StructureMap), How could one utilise such a tool in the given Unit + Integration test setup?
can anyone share some wisdom? Thanks
I don't think you should physically separate the two. A good solution is to put the Microsoft.TeamFoundation.PowerTools.Tasks.CategoryAttribute above your tests to identify regular and integration tests. When running tests (even with MSBuild) you can decide to run only the tests you're interested in.
Alternatively you can put them in seperate namespaces.
For code that will be executed in setup & teardown phases, the base class approach would work well. For integration tests, you can extract the functionality of your unit tests into well-parameterized non-test methods (preferably placed in another namespace) and call these "common" methods from both unit and integration tests. Putting unit tests, integration tests and common methods into separate namespaces would suffice, there would be no need for extra assemblies.
One approach would be to create a separate file with helper methods that would be used across multiple testing contexts, and then include that file in both your unit tests and your functional tests. For the parts that vary, you could use dependency injection - for example, by passing in different factories. In the unit tests, the factory could build a fake object, and in the functional tests it could insert a real object in to your test database.
Whether you split the tests into two projects or keep them in one might depend on the number of classes/tests you have. Too many classes in a single project would make it difficult to dig through. If you do split them out, helper/common methods could be thrown into a third assembly, or you could make them public in the unit test assembly, and let the integration assembly reference that one. Make things only as complex as you have to.
On our project we have both integration and unit tests together but in separate folders. Our project layout is such that we have separate assemblies for the main sections (Domain, Services, etc). Each assembly has a matching test assembly. Test assemblies are allowed to reference other test assemblies.
This means Services.Test can reference Domain.Test which makes sense to us because Services references Domain in the actual code.
In terms of reusable pieces we have
Builders - These provide a fluent interface for creating the most important/complex objects in our domain. These live in the main test folder for our domain. Our domain test assembly is referenced by all other test assemblies.
Mothers - These insert data into the database. They give back an Id for the inserted row which can be used to load the object if required. These live in the main test folder for our services.
Helpers - These are guys that do small things throughout our testing. For instance we prefer to allow access to collections via IEnuermable so we have a CollectionHelper.AssertCountIsEqualTo<_T>(int count, IEnumerable<_T> collection, string message) which wraps the IEnumerable in a List and asserts a count. Our Helpers all live in a common test which every other test references.
As for an IoC container if you can use one on your project they can be a huge help not only in testing (via auto mocking) but also in general development. With the overheard of registering everything with the contain though it might be a bit much for just testing.
After some experimenting this is how you can re-use test methods:
public abstract class TestBase
{
[TestMethod]
public void BaseTestMethod()
{
Assert.IsTrue(true);
}
}
[TestClass]
public class UnitTest : TestBase
{
}
[TestClass]
public class IntegrationTest : TestBase
{
}
The unit and integration test class will pick up the base class test methods and run them as two separate tests.
You should be able to create a parametised constructor on the base class to inject your mocks or resources.
I think this method can olny be used with classed within the same assembly. So it looks like the single assembly approach will have to do for now.
Thanks for the tips ppl!
If the only difference between many of your unit tests and the corresponding integration tests is that the latter use "real" ressources rather than fakes (mocks), one approach is the following:
Make a flag is_unit_test available to your test class from the outside
In the class setup, make fake or real resources available depending on the flag. For instance if you need to use a DB API that is either real (an instance of class DBreal) or fake (an instance of class DBfake), your initialization may look like if is_unit_test then this.dbapi = new DBfake else this.dbapi = new DBreal. (DBreal and DBfake need to conform to the same interface, let's call it DBapi.)
From the point of view of your test methods, step 2 amounts to (manual) Dependency Injection: The method does not know what class actually implements its dependency (the DB API). Rather, the dependency is injected into the method from the outside.
Where your test cases require the DB API, they use this.dbapi
Now you execute one and the same test class with the flag set for unit testing and without the flag set for integration testing. (How to make the flag available depends on your unit testing framework.)
Obviously, the same approach can be used if you need more than one resource in a test class.
Some people will find the explicit if in step 2 ugly. To make it more "elegant", you could employ an Inversion of Control (IoC) container (in Java for instance Spring or PicoContainer) to semi-automate the Dependency Injection instead. The initialization would then look like this.dbapi = myContainer.create(DBapi).
In simple cases, an IoC container will only complicate things, because configuring the container is not trivial, involves learning, opens the possibility of a new class of mistakes, and involves additional files.
In more complex cases however, the container makes things easier, because if the creation of your resources requires still other resources, the container will take care of their initialization as well and complexity would indeed go down. But unless you really get there, I suggest to KISS.
Unless you have an important reason for separate assemblies, they violate KISS. I suggest to wait for that reason first.
(Note that some people may tell you that Dependency Injection is only done at the class level.
I consider this unwarranted dogmatism. Injection simply means that a caller does not know the exact class it is calling, no matter how it obtained the object. It often becomes more useful when applied at the class level, but depending on your test framework this may make things overly complicated in the above case. Note that some test frameworks have their own injection capabilities, though.)
I have an existing VS 2005 Std .NET Compact Framework application that I want to do some major refactorings on. Currently there is no unit testing in place, but I want to add this before messing with the code. I have no practical experience with unit testing, even though I know the theory (just never got around actually implementing it; I know: shame on me :-))
Here are some questions I am pondering at the moment:
a) As a beginner, should I use NUnit or NUnitLite (which claims to be easier to use)?
b) Should I aim for running the tests on the mobile device or on the desktop (except for device-specific code of course)? Currently the desktop looks more appealing, especially for including the tests in automated builds...
c) How is the class that I want to test usually included in the test project? My application is a .EXE file, i.e. I can not just reference it like a .DLL assembly from the test project (or can I? Never tried this ...). I checked various NUnit tutorials but either found no mention of that, or one tutorial suggested to copy and paste the class that I want to test into the test project (yuk!). Should I link to the original source code file in my test project? What about private methods, or dependencies on other classes?
d) Should I start modifying my original code to allow better testability, e.g. make private methods public, decouple etc.? This is a bit like refactoring before being able to test, which does not sound good to me ... Or is it better practice to not touch the original code at all in the beginning, even if this means less code coverage etc.?
e) Should I look into any other tools or addons that most people use?
Thanks in advance for any answers (I also appreciate answers if they are only to one or some of the above items).
First, I would recommend you a good book on unit testing: Pragmatic Unit Testing in C#.
It will introduce you to NUnit, but what's more important, the author will provide you a lot of advices how to write good unit tests in general. The xUnit test frameworks are not very complex and you'll get used to their API/workflow very quick. Challenging is the actual process of identifying boundary conditions, decrease coupling and design for testability. It's available as an eBook (PDF) or a printed copy.
Regarding your actual questions (the book will give you some answers, too):
#a) I've no experience with NUnit lite, thus I cannot give you any advice on this point.
#b) Unit tests are supposed to be very local in regard of their dependencies. You aim to test classes independent of each other, thus there would be no need to deploy it on a mobile device first. You won't run the full app, just test components in isolation. Hence, I would recommend to use your desktop machine as the target for your unit test environment. You'll get better turn-around times, too.
#c) You have to reference the assembly that contains the classes you want to test in your test project. The test project will be an assembly itself (DLL). A test runner executes this assembly and uses the stored meta information to run the contained test cases.
#d) It depends a lot on the state and design of your software. But in general I would use a divide and conquer strategy: Introduce interfaces between classes and start to refactor step by step. Write unit tests before you start to change the implementation. The interfaces keep the contracts up and running, but you can change the underlying implementation if necessary. Don't make private methods public just to make them testable. Private methods are internal helpers of the class that support public methods in doing their job. Since you test your public methods you'll assert that your private methods do the right thing.
#e) A helpful add in for Visual Studio is TestDriven.Net. It allows you to run NUnit tests directly from the IDE without changing to NUnit's GUI or console runner.
#c) I haven't tried it, but I would think VisualStudio would let you add a project reference from your test assembly to your actual code assembly, even if its an exe.
As for private methods and such, generally I don't test private methods. In theory, all the private stuff should be used by public or internal methods, so testing those should indirectly test the privates.
I do test public and internals though. One thing I find very helpful is the InternalsVisibleTo attribute:
[assembly:InternalsVisibleTo("MyTestAssembly")]
which you can use to make the internals of one assembly visible to another. I use this attribute to expose the internals to my test assembly, so that it can directly reference them.
I understand the need to test a class that has logic (for instance, one that can calculate discounts), where you can test the actual class.
But I just started writing unit tests for a project that will act as a repository (get objects from a database). I find myself writing a 'fake' repository that implements an ISomethingRepository interface. It uses a Dictionary<Guid, Something> for storage internally. It implements the Add(Something) and GetById(Guid) methods of the interface.
Why am I writing this? Nothing I'm writing will actually be used by the software when it's deployed, right? I don't really see the value of this exercise.
I also got the advice to use a mock object that I can setup in advance to meet certain expectations. That seems even more pointless to me: of course the test will succeed, I have mocked/faked it to succeed! And I'm still not sure the actual software will perform as it should when connecting to the database...
confused...
Can someone point me in the right direction to help me understand this?
Thank you!
You are not testing your mock object but some other class that is interacting with it. So you could for example test that a controller forwards a save method call to your fake repository. There is something wrong if you are "testing your fake objects"
Don't test the mock class. Do test the production class using the mock class.
The whole point of the test support class is to have something that you can predict its behavior. If you need to test the test support class in order to predict its behavior, there is a problem.
In the fake database article you linked in a comment, the author needs to unit test his fake database because it is his product (at least in the context of the article).
Edit: updated terms to be more consistent.
Mock - created by mocking framework
Fake - created manually, might actually function some.
Test Support - Mocks, Fakes, Stubs, and all the rest. Not production.
The purpose of the mock/stub object is not to be tested instead of the unit you're trying to test, it's to allow you to test that unit without needing other classes.
It's basically so that you can test classes one at a time without having to test all the classes they're also dependent on.
You should not be testing the mock class.
What you normally do is: you create mock classes for all the classes that the class you are testing interact with.
Let's say you are testing a class called Bicycle which takes in the constructor objects of classes Wheel, Saddle, HandleBar,etc.
And then within the class Bike you you want to test test its method GetWeight which probably iterates through each part and calls property/method Weight of them and then returns the total.
What you do:
you write a mock class for each part
(Wheel, saddle etc) which simply
implements the Weight bit
then you pass those mock classes to the Bicycle
test the GetWeight method on the Bicycle class
It that way you can focus on testing the GetWeight on the Bicycle class, in a manner that is independent on other classes (say they are not implemented yet, not deterministic etc.)
Who watches the watchers?
It is interesting for example if the mock implementation throws specific Exceptions for the corner cases, so you know that the classes that use or depend the IRepositorySomething can handle the exceptions that are thrown in real life. Some of these exceptions you can't generate easily with a test database.
You do not test the Mock object with a unit test, but you use it to test classes that depend on it.
Instead of writing a fake class by yourself, you can use a tool (like Rhino or Typemock) to mock it. It is much easier than writing all the mocks yourself. And like others said, there's no need to test fake code, which is no code if you use the tool.
I have actually found two uses for the mock classes that we use in repository implementation testing.
The first is to test the services that use an implementation of the "ISomethingRepository" equivalent that you mention. However, our repository implementations are created by a factory. This means that we do write tests against the "ISomethingRepository", but not against the "MockSomethingRepository" directly. By testing against the interface, we can easily assert that the code coverage for our tests cover 100% of the interface. Code reviews provide simple verification that new interface members are tested. Even if the developers are running against the mock that the factory returns, the build server has a different configuration that tests against the concrete implementation that the factory returns within the nightly builds. It provides the best of both worlds, in terms of test coverage and local performance.
The second use is one that I am surprised that no one else has mentioned. My team is responsible for the middle tier. Our web developers are responsible for the front end of the web products. By building out mock repository implementations, there is not the artificial obstacle of waiting for the database to be modeled and implemented prior to the front-end work starting. Views can be written that will be built off of the mock to provide a minimal amount of "real" data to meet the expectations of the web developers, as well. For example, data can be provided to contain minimum and maximum length string data to verify that neither break their implementation, etc.
Since the factories we use are wired as to which "ISomethingRepository" to return, we have local testing configurations, build testing configurations, production configurations, etc. We purposely are trying to make sure that no team on the project has unreasonable wait times because of another team's implementation time. The largest chunk of wait time is still provided by the development team, but we are able to crank out our domain objects, repositories, and services at a faster pace than the front-end development.
Of course, YMMV. ;-)
You write "fake" class called Stub or Mock object because you want to test an implementation in a simple way without testing the real concrete class. The purpose is to simplify the testing by testing only the Interface (or abstract class).
In your example, you are testing something that has a dictionnary. It might be fill up in real by the database or have a lot of logic behind it. In your "fake" object, you can simplify everything by having all data constant. This way you test only the behavior of the interface and not how the concrete object is built.
There is generally no need to run classical unit tests in the Data Access Layer.
Perhaps you can write integrational style unit test for your Data Acess Classes, that is, Integration Test (= integrating your Data Access Layer Code with the DB) using the features of Unit Testing Frameworks.
For example, in a Spring project you can use Spring Testcontext to start your Spring context inside a unit test, and then connect to a real database and test that the queries returns correct results. You need probably an own database for unit tests, or perhaps you can connect them with a developer DB.
Have a look at the following article for a good explanation of this:
https://web.archive.org/web/20110316193229/http://msdn.microsoft.com/en-us/magazine/cc163358.aspx
Basically, if you write a fake object and it turns out to be fairly complex, it is sometimes worth it to unit test the fake to make sure it works as expected.
Since a repository can be complex, writing unit tests for it often makes sense.