I'm trying my hand at behavior driven development and I'm finding myself second guessing my design as I'm writing it. This is my first greenfield project and it may just be my lack of experience. Anyway, here's a simple spec for the class(s) I'm writing. It's written in NUnit in a BDD style instead of using a dedicated behavior driven framework. This is because the project targets .NET 2.0 and all of the BDD frameworks seem to have embraced .NET 3.5.
[TestFixture]
public class WhenUserAddsAccount
{
private DynamicMock _mockMainView;
private IMainView _mainView;
private DynamicMock _mockAccountService;
private IAccountService _accountService;
private DynamicMock _mockAccount;
private IAccount _account;
[SetUp]
public void Setup()
{
_mockMainView = new DynamicMock(typeof(IMainView));
_mainView = (IMainView) _mockMainView.MockInstance;
_mockAccountService = new DynamicMock(typeof(IAccountService));
_accountService = (IAccountService) _mockAccountService.MockInstance;
_mockAccount = new DynamicMock(typeof(IAccount));
_account = (IAccount)_mockAccount.MockInstance;
}
[Test]
public void ShouldCreateNewAccount()
{
_mockAccountService.ExpectAndReturn("Create", _account);
MainPresenter mainPresenter = new MainPresenter(_mainView, _accountService);
mainPresenter.AddAccount();
_mockAccountService.Verify();
}
}
None of the interfaces used by MainPresenter have any real implementations yet. AccountService will be responsible for creating new accounts. There can be multiple implementations of IAccount defined as separate plugins. At runtime, if there is more than one then the user will be prompted to choose which account type to create. Otherwise AccountService will simply create an account.
One of the things that has me uneasy is how many mocks are required just to write a single spec/test. Is this just a side effect of using BDD or am I going about this thing the wrong way?
[Update]
Here's the current implementation of MainPresenter.AddAccount
public void AddAccount()
{
IAccount account;
if (AccountService.AccountTypes.Count == 1)
{
account = AccountService.Create();
}
_view.Accounts.Add(account);
}
Any tips, suggestions or alternatives welcome.
When doing top to down development it's quite common to find yourself using a lot of mocks. The pieces you need aren't there so naturally you need to mock them. With that said this does feel like an acceptance level test. In my experience BDD or Context/Specification starts to get a bit weird at the unit test level. At the unit test level I'd probably be doing something more along the lines of...
when_adding_an_account
should_use_account_service_to_create_new_account
should_update_screen_with_new_account_details
You may want to reconsider your usage of an interface for IAccount. I personally stick
with keeping interfaces for services over domain entities. But that's more of a personal preference.
A few other small suggestions...
You may want to consider using a Mocking framework such as Rhino Mocks (or Moq) which allow you to avoid using strings for your assertions.
_mockAccountService.Expect(mock => mock.Create())
.Return(_account);
If you are doing BDD style one common pattern I've seen is using chained classes for test setup. In your example...
public class MainPresenterSpec
{
// Protected variables for Mocks
[SetUp]
public void Setup()
{
// Setup Mocks
}
}
[TestFixture]
public class WhenUserAddsAccount : MainPresenterSpec
{
[Test]
public void ShouldCreateNewAccount()
{
}
}
Also I'd recommend changing your code to use a guard clause..
public void AddAccount()
{
if (AccountService.AccountTypes.Count != 1)
{
// Do whatever you want here. throw a message?
return;
}
IAccount account = AccountService.Create();
_view.Accounts.Add(account);
}
The test life support is a lot simpler if you use an auto mocking container such as RhinoAutoMocker (part of StructureMap) . You use the auto mocking container to create the class under test and ask it for the dependencies you need for the test(s). The container might need to inject 20 things in the constructor but if you only need to test one you only have to ask for that one.
using StructureMap.AutoMocking;
namespace Foo.Business.UnitTests
{
public class MainPresenterTests
{
public class When_asked_to_add_an_account
{
private IAccountService _accountService;
private IAccount _account;
private MainPresenter _mainPresenter;
[SetUp]
public void BeforeEachTest()
{
var mocker = new RhinoAutoMocker<MainPresenter>();
_mainPresenter = mocker.ClassUnderTest;
_accountService = mocker.Get<IAccountService>();
_account = MockRepository.GenerateStub<IAccount>();
}
[TearDown]
public void AfterEachTest()
{
_accountService.VerifyAllExpectations();
}
[Test]
public void Should_use_the_AccountService_to_create_an_account()
{
_accountService.Expect(x => x.Create()).Return(_account);
_mainPresenter.AddAccount();
}
}
}
}
Structurally I prefer to use underscores between words instead of RunningThemAllTogether as I find it easier to scan. I also create an outer class named for the class under test and multiple inner classes named for the method under test. The test methods then allow you to specify the behaviors of the method under test. When run in NUnit this gives you a context like:
Foo.Business.UnitTests.MainPresenterTest
When_asked_to_add_an_account
Should_use_the_AccountService_to_create_an_account
Should_add_the_Account_to_the_View
That seems like the correct number of mocks for a presenter with a service which is supposed to hand back an account.
This seems more like an acceptance test rather than a unit test, though - perhaps if you reduced your assertion complexity you would find a smaller set of concerns being mocked.
Yes, your design is flawed. You are using mocks :)
More seriously, I agree with the previous poster who suggests your design should be layered, so that each layer can be tested separately. I think it is wrong in principle that testing code should alter the actual production code -- unless this can be done automatically and transparently the way code can be compiled for debug or release.
It's like the Heisenberg uncertainty principle - once you have the mocks in there, your code is so altered it becomes a maintenance headache and the mocks themselves have the potential to introduce or mask bugs.
If you have clean interfaces, I have no quarrel with implementing a simple interface that simulates (or mocks) an unimplemented interface to another module. This simulation could be used in the same way mocking is, for unit testing etc.
You might want to use MockContainers in order to get rid of all the mock management, while creating the presenter. It simplifies unit tests a lot.
This is okay, but I would expect an IoC automocking container in there somewhere. The code hints at the test writer manually (explicitly) switching between mocked and real objects in tests which should not be the case because if we are talking about a unit test (with unit being just one class), it's simpler to just auto-mock all other classes and use the mocks.
What I'm trying to say is that if you have a test class that uses both mainView and mockMainView, you don't have a unit test in the strict sense of the word -- more like an integration test.
It is my opinion that if you find yourself needing mocks, your design is incorrect.
Components should be layered. You build and test components A in isolation. Then you build and test B+A. Once happy, you build layer C and test C+B+A.
In your case you shouldn't need a "_mockAccountService". If your real AccountService has been tested, then just use it. That way you know any bugs are in MainPresentor and not in the mock itself.
If your real AccountService hasn't been tested, stop. Go back and do what you need to ensure it is working correctly. Get it to the point where you can really depend on it, then you won't need the mock.
Related
Is there a collection of unit tests that will verify my implementation of an interface is correct? Specifically, I am using an implementation of ISet<T> and would like to basically plug it into a unit test to verify my implementation is correct. (Rather than me coming up with 5-20 unit tests for good coverage)
It would seem like all interfaces could be have some general unit tests written for them.
There is helpful post regarding the matter in Software Engineering the code will look something like this:
private void Test<TService,TFilter>(string urlSuffix)
where TService : SoapHttpClientProtocol, new()
where TFilter : new()
{
string serviceUrl = Helper.GetBaseUrl() + urlSuffix;
TService service = new TService();
service.Credentials = Helper.GetCredentials();
service.Url = serviceUrl;
TFilter[] filter = { new TFilter() };
service.ReadMultiple(filter, null, 0);
}
[TestMethod]
public void PlaceOfWork()
{
Test<PlaceOfWork_Service,PlaceOfWork_Filter>("PlaceOfWork");
}
This is a generic method to mock service connection and access but it can easily be applied to interfaces as well.
However Be ware that if you use generics in unit test you lose granularity, this is because your test is going to cover multiple cases.
It will soon become unclear what you are testing in each interface
If your test fails after the first one, you fail to uncover more bugs resulting in fail masking..
Check this solution, twitch with it a little bit in order to understand all of it's advantages and disadvantages and read similar posts as well.
I found what I was after here: https://github.com/dbrizov/TelerikHomeworks/blob/master/C%23/C%23%20HQC/Code%20Formatting/CSharpFormatting/lib/PowerCollections/Source/UnitTests/InterfaceTests.cs
It's from https://archive.codeplex.com/?p=powercollections
This question follows on from my previous question here: How to use OneTimeSetup? and specifically one of the answerers answer. Please see the code below:
[TestFixture]
public class MyFixture
{
IProduct Product;
[OneTimeSetUp]
public void OneTimeSetUp()
{
IFixture fixture = new Fixture().Customize(new AutoMoqCustomization());
Product = fixture.Create<Product>();
}
//tests to follow
}
Is AutoMoq used to create mocks only? The reason I ask is because I was reading a question on here earlier where the answerer implied that it is also used to create normal types i.e. not Mocks.
I want to test the Core element of my Onion, which has no dependencies. Therefore should I be using AutoFixture?
The AutoMoq Glue Library gives AutoFixture the additional capabilities of an Auto-Mocking Container; that is, not only can it compose normal objects for you - it can also supply mock objects to your objects, should they be so required.
AutoFixture itself is not an Auto-Mocking Container, but rather a library that automates the Fixture Setup phase of the Four Phase Test pattern, as described in xUnit Test Patterns. It also enables you to automate code associated with the Test Data Builder pattern.
It was explicitly designed as an alternative to Implicit Setup, so I think it makes little sense to use it together with a setup method and mutable class field as this question suggests. In other words, the whole point of AutoFixture is that it enables you to write independent unit tests like this:
[TestFixture]
public class MyFixture
{
[Test]
public void MyTest()
{
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var product = fixture.Create<Product>();
// Use product, and whatever else fixture creates, in the test
}
}
You definitely can use it to test your units even when they have no dependencies, but in that case, you probably don't need the AutoMoq Customization.
I don't have a lot of experience with unit testing. For example I have simple method in the application:
public void GetName()
{
UserRights rights = new UserRights(new DatabaseContext());
string test = rights.LookupNameByID("12345");
Console.WriteLine(test);
}
In this case I'm able to test all methods of UserRights class by passing mocked DatabaseContext, but how can I test GetName() method? What is the best practice? Where DatabaseContext should be created?
If you want to test the GetName method in a properly isolated way (i.e. a Unit Test) then you can't use new to create the UserRights instance in the method itself; because a test is really just another client of the code, therefore it can't (and shouldn't) know anything about how GetName works internally
So what this means is that for a proper Unit Test you must be able to replace all dependencies of a method with ones that the client fully controls - in the case, the code in the Unit Test is the client.
In your posted code, the client code has no control at all over UserRights nor DatabaseContext, so this is the first thing that has to change.
You need to rework your code so that the UserRights implementation can be supplied by the client. In fact once that's done, the problem about where DatabaseContext comes from is actually irrelevant for the Unit test because it doesn't care about how UserRights itself performs its tasks!
There are a number of ways of doing this; you can use Mocks or Stubs, you can use Constructor or Method injection, you could use a UserRights factory. Here is an example of using very simple stubs which IMHO is the best way to start and avoids having to learn a Mocking framework -- I personally would use Mocks for this but that's cos I am lazy :)
(code below assumes the class containing GetName is called "UserService", and uses xUnit framework; but MSTest will work just fine too)
Let's suppose you have control over the code of UserService so you can make the LookupNameByID method virtual (if you can't, then you may have to go the route if interfaces and mocks)
public class UserRights
{
public virtual LookupNameByID(string id)
{
//does whatever a UserRights does.
}
}
public class UserService
{
readonly UserRights _rights;
public UserService(UserRights rights)
{
_rights=rights; //null guard omitted for brevity
}
public string GetName(string id)
{
return _rights.LookupNameByID(id);
}
}
now in your unit test code suppose you create a sub-class of UserRights like this:
public class ExplodingUserRights: UserRights
{
public override string LookupNameByID(string id)
{
throw new Exception("BOOM!");
}
}
Now you can write a test to see how GetName reacts when something bad happens:
[Fact]
public void LookupNameByID_WhenUserRightsThrowsException_DoesNotReThrow()
{
//this test will fail if an exception is thrown, thus proving that GetName doesn't handle exceptions correctly.
var sut = new UserService(new ExplodingUserRights()); <-Look, no DatabaseContext!
sut.GetName("12345");
}
and one for when good things happen:
public class HappyUserRights: UserRights
{
public override string LookupNameByID(string id)
{
return "yay!";
}
}
[Fact]
public void LookupNameByID_ReturnsResultOfUserRightsCall()
{
//this test will fail if an exception is thrown, thus proving that GetName doesn't handle exceptions correctly.
var sut = new UserService(new HappyUserRights());
var actual = sut.GetName("12345");
Assert.Equal("yay!",actual);
}
and so on. Note that we never went anywhere near DatabaseContext, because that's a problem you only have to solve when you unit test the UserRights class itself. (and at that point I would probably recommend using Jeroen's advice from his linked article,and do an integration test, unless setup of a database for each test is something you can't or won't do, in which case you need to use interfaces and mocks)
Hope that helps.
Separating your codes reliance on DB Context is something you will want to investigate, this can be accomplished using the Repository pattern. Since you're passing the DB Context into your objects constructor, in this case UserRights, you can pretty easily change your code to take in an Interface (or simply add an overloaded contructor to the class that accepts an interface, then call that in your unit tests, preserving any existing code). There are lots of ways to get this done, a quick Google search yielded the following article:
http://romiller.com/2012/02/14/testing-with-a-fake-dbcontext/
http://www.codeproject.com/Articles/207820/The-Repository-Pattern-with-EF-code-first-Dependen
Once your class can accept an interface rather than (or as an alternative to) the strongly typed DB Context object you can use a Mock framework to assist with testing. Take a look at Moq for examples on how to use these in your unit tests https://github.com/Moq/moq4/wiki/Quickstart
Be Aware: Moq can become difficult to work with when your tests require data that is related via foreign keys, the syntax can be complicated to get your head around. One thing to watch out for is the temptation to make changes to your code just to make a unit test easier to set up, while there may be value in making this change it also may indicate that you need to re-think your unit test rather than violate your applications architecture and/or design patterns
I'm trying to understand Inversion of Control and how it helps me with my unit testing. I've read several online explanations of IOC and what it does, but I'm just not quite understanding it.
I developed a sample project, which included using StructureMap for unit testing. StructureMap setup code like the following:
private readonly IAccountRepository _accountRepository
public Logon()
{
_accountRepository = ObjectFactory.GetInstance<IAccountRepository>();
}
The thing I'm not understanding though, is as I see it, I could simply declare the above as the following:
AccountRepository _accountRepository = new AccountRepository();
And it would do the same thing as the prior code. So, I was just wondering if someone can help explain to me in a simple way, what the benefit of using IOC is (especially when dealing with unit testing).
Thanks
Inversion of Control is the concept of letting a framework call back into user code. It's a very abstract concept but in essence describes the difference between a library and a framework. IoC can be seen as the "defining characteristic of a framework." We, as program developers, call into libraries, but frameworks instead call into our code; the framework is in control, which is why we say the control is inverted. Any framework supplies hooks that allow us to plug in our code.
Inversion of Control is a pattern that can only be applied by framework developers, or perhaps when you're an application developer interacting with framework code. IoC does not apply when working with application code exclusively, though.
The act of depending on abstractions instead of implementations is called Dependency Inversion, and Dependency Inversion can be practiced by both application and framework developers. What you refer to as IoC is actually Dependency Inversion, and as Krzysztof already commented: what you're doing is not IoC. I'll discuss Dependency Inversion for the remainder of my answer.
There are basically two forms of Dependency Inversion:
Service Locator
Dependency Injection.
Let's start with the Service Locator pattern.
The Service Locator pattern
A Service Locator supplies application components outside the [startup path of your application] with access to an unbounded set of dependencies. As its most implemented, the Service Locator is a Static Factory that can be configured with concrete services before the first consumer begins to use it. (But you’ll equally also find abstract Service Locators.) [source]
Here's an example of a static Service Locator:
public class Service
{
public void SomeOperation()
{
IDependency dependency =
ServiceLocator.GetInstance<IDependency>();
dependency.Execute();
}
}
This example should look familiar to you, because this what you're doing in your Logon method: You are using the Service Locator pattern.
We say that a Service Locator supplies access to an unbounded set of dependencies, because the caller can pass in any type it wishes at runtime. This is opposite to the Dependency Injection pattern.
The Dependency Injection pattern
With the Dependency Injection pattern (DI), you statically declaring a class's required dependencies; typically, by defining them in the constructor. The dependencies are made part of the class's signature. The class itself isn't responsible for getting its dependencies; that responsibility is moved up up the call stack. When refactoring the previous Service class with DI, it would likely become the following:
public class Service
{
private readonly IDependency dependency;
public Service(IDependency dependency)
{
this.dependency = dependency;
}
public void SomeOperation()
{
this.dependency.Execute();
}
}
Comparing both patterns
Both patterns are Dependency Inversion, since in both cases the Service class isn't responsible of creating the dependencies and doesn't know which implementation it is using. It just talks to an abstraction. Both patterns give you flexibility over the implementations a class is using and thus allow you to write more flexible software.
There are, however, many problems with the Service Locator pattern, and that's why it is considered an anti-pattern. You are already experiencing these problems, as you are wondering how Service Locator in your case helps you with unit testing.
The answer is that the Service Locator pattern does not help with unit testing. On the contrary: it makes unit testing harder compared to DI. By letting the class call the ObjectFactory (which is your Service Locator), you create a hard dependency between the two. Replacing IAccountRepository for testing, also means that your unit test must make use of the ObjectFactory. This makes your unit tests harder to read. But more importantly, since the ObjectFactory is a static instance, all unit tests make use of that same instance, which makes it hard to run tests in isolation and swap implementations on a per-test basis.
I used to use a static Service Locator pattern in the past, and the way I dealt with this was by registering dependencies in a Service Locator that I could change on a thread-by-thread basis (using [ThreadStatic] field under the covers). This allowed me to run my tests in parallel (what MSTest does by default) while keeping tests isolated. The problem with this, unfortunately, was that it got complicated really fast, it cluttered the tests with all kind of technical stuff, and it made me spent a lot of time solving these technical problems, while I could have been writing more tests instead.
But even if you use a hybrid solution where you inject an abstract IObjectFactory (an abstract Service Locator) into the constructor of Logon, testing is still more difficult compared to DI because of the implicit relationship between Logon and its dependencies; a test can't immediately see what dependencies are required. On top of that, besides supplying the required dependencies, each test must now supply a correctly configured ObjectFactory to the class.
Conclusion
The real solution to the problems that Service Locator causes is DI. Once you statically declare a class's dependencies in the constructor and inject them from the outside, all those issues are gone. Not only does this make it very clear what dependencies a class needs (no hidden dependencies), but every unit test is itself responsible for injecting the dependencies it needs. This makes writing tests much easier and prevents you from ever having to configure a DI Container in your unit tests.
The idea behind this is to enable you to swap out the default account repository implementation for a more unit testable version. In your unit tests you can now instantiate a version that doesn't make a database call, but instead returns back fixed data. This way you can focus on testing the logic in your methods and free yourself of the dependency to the database.
This is better on many levels:
1) Your tests are more stable since you no longer have to worry about tests failing due to data changes in the database
2) Your tests will run faster since you don't call out to an external data source
3) You can more easily simulate all your test conditions since your mocked repository can return any type of data needed to test any condition
The key to answer your question is testability and if you want to manage the lifetime of the injected objects or if you are going to let the IoC container do it for you.
Let's say for example that you are writing a class that uses your repository and you want to test it.
If you do something like the following:
public class MyClass
{
public MyEntity GetEntityBy(long id)
{
AccountRepository _accountRepository = new AccountRepository();
return _accountRepository.GetEntityFromDatabaseBy(id);
}
}
When you try to test this method you will find that there are a lot of complications:
1. There must be a database already set up.
2. Your database needs to have the table that has the entity you're looking for.
3. The id that you are using for your test must exist, if you delete it for whatever reason then your automated test is now broken.
If instead you have something like the following:
public interface IAccountRepository
{
AccountEntity GetAccountFromDatabase(long id);
}
public class AccountRepository : IAccountRepository
{
public AccountEntity GetAccountFromDatabase(long id)
{
//... some DB implementation here
}
}
public class MyClass
{
private readonly IAccountRepository _accountRepository;
public MyClass(IAccountRepository accountRepository)
{
_accountRepository = accountRepository;
}
public AccountEntity GetAccountEntityBy(long id)
{
return _accountRepository.GetAccountFromDatabase(id)
}
}
Now that you have that you can test the MyClass class in isolation without the need for a database to be in place.
How is this beneficial? For example you could do something like this (assuming you are using Visual Studio, but the same principles apply to NUnit for example):
[TestClass]
public class MyClassTests
{
[TestMethod]
public void ShouldCallAccountRepositoryToGetAccount()
{
FakeRepository fakeRepository = new FakeRepository();
MyClass myClass = new MyClass(fakeRepository);
long anyId = 1234;
Account account = myClass.GetAccountEntityBy(anyId);
Assert.IsTrue(fakeRepository.GetAccountFromDatabaseWasCalled);
Assert.IsNotNull(account);
}
}
public class FakeRepository : IAccountRepository
{
public bool GetAccountFromDatabaseWasCalled { get; private set; }
public Account GetAccountFromDatabase(long id)
{
GetAccountFromDatabaseWasCalled = true;
return new Account();
}
}
So, as you can see you are able, very confidently, to test that the MyClass class uses an IAccountRepository instance to get an Account entity from a database without the need to have a database in place.
There are a million things you can still do here to improve the example. You could use a Mocking framework like Rhino Mocks or Moq to create your fake objects instead of coding them yourself like I did in the example.
By doing this the MyClass class is completely independent of the AccountRepository so that's when the loosley coupled concept comes into play and your application is testable and more maintainable.
With this example you can see the benefits of IoC in itself. Now if you DO NOT use an IoC container you do have to instantiate all the dependencies and inject them appropriately in a Composition Root or configure an IoC container so it can do it for you.
Regards.
A month ago I finished reading the book "Art of Unit Testing" and today I finally had time to start using Rhino Mocks with unit testing a service that sends/receives messages to devices (UDP) and saves/loads data from the database.
Off course I want to isolate the database and the UDP communication.
For example for database access, we have some classes with static methods, let's call them:
AreaADBAccess
AreaBDBAccess
AreaCDBAccess
These classes had static methods that executed the database access.
To be able to stub them I made their methods public virtual.
Then I started refactoring the code to be able to replace the instance of these classes on the code.
After trying different things, I ended up with a factory class that seems to make things so easy.
public class ObjectFactory
{
private static Dictionary<Type, object> Instances = new Dictionary<Type, object>();
public static T GetInstance<T>() where T : new()
{
if(Instances.ContainsKey(typeof(T)))
return (T)Instances[typeof(T)];
return new T();
}
public static void SetInstance<T>(object obj)
{
Instances[typeof(T)] = obj;
}
}
Then on the code, I can use
private AreaADBAccess DBAccess = ObjectFactory.GetInstance<AreaADBAccess>();
And on the test method I do something like
AreaADBAccess dbAccess = mocks.Stub<AreaADBAccess>();
using (mocks.Record())
{
...
}
ObjectFactory.SetInstance<AreaADBAccess>(dbAccess);
//Invoke the test method
...
This is a first solution and I realize that it can be done in a better way.
Can you now comment it and point me to the best practices?
Can you also explain to me why I would want to have an interface instead of defining the methods as virtual? It seems useless to repeat the method headers in 2 places.
Thanks!
Probably you could make use of IoC containers like, Windsor, StructureMap or Ninject, which would make your life much easier, and in fact they also work as "factory" you have created manually, but are much more powerful.
Also there are automocking containers which will automatically create mock dependencies for your classes so you can save additional lines of code, and make your test less fragile.
As for question regarding the need for interface instead of classes, its basically the Dependency Inversion Principle, which states that higher level modules (classes) should not depend on lower level modules (classes), both of them should depend on abstractions. Interfaces are those abstractions.
I suggest you would take a look at S.O.L.I.D principles which will make your life much more easier, at least they did to me..