Posts tagged Tests
DDD, BDD, TDD…. What’s the Difference?
1For me software development has become more than just writing code, although ultimately that is what it’s about; a developer writing applications that work and serve a function. As I’ve progressed through my development life, I have picked up techniques and methodologies to help me develop a better application. Some of these techniques are Domain Driven Design (DDD), Behavior Driven Development (BDD), and Test
Driven Development (TDD). Jeez that’s a lot of D’s! What’s the difference between all of these methodologies and when to use them? Well I’m about to tell you where they fit into my development ecosystem. Again, this is where I’ve found these methodologies to work the best for me.
Domain Driven Design (DDD)
I’ve always thought of DDD as a mindset rather than a code writing methodology. DDD’s main focus is create a dialogue between developers and the domain they are attempting to develop in. For example, if I were writing a blog, then my discussions and inevitably my code would include words like “posts”, “tags”, and “categories”. I’ve always found DDD to be easy for developers to understand. It doesn’t require any tools except for a good whiteboard and some developers willing to talk to each other and their business partners. Below are the necessities that I perceive to properly implement DDD.
DDD Necessities:
- Whiteboard
- Open dialogue
- Domain experts
- An open mind
Behavior Driven Development (BDD)
I use BDD to express my application’s intent (with code) within my project. The specifications are written using stories and scenarios, and it is my job to make sure that those stories are true through functionality. BDD is cool because intentions are visible, and all your BDD stories are written in English that is understandable to your domain experts. BDD and DDD are tightly interlocked because your stories will most likely come out of your DDD sessions with your domain experts. Below are a overview of the tools needed to implement BDD.
BDD Necessities:
- BDD Framework (For .Net : MSPEC, StoryQ, SpecUnit.Net, SpecFlow)
- Story (Test) Runner
- Discipline of Steel ( the most important thing)
Test Driven Development (TDD)
I still use test driven development, but in a different scope. TDD has turned into my debugging approach of choice when dealing with a client’s code. I attempt to write a unit test to isolate issues. During this process, I can re-factor and learn more about the newly presented code base. Once I can reproduce the bug through a unit test, I can start thinking about what I need to do to solve the issue. This method of debugging only works with code based bugs, and not things like memory leaks.
TDD Necessities:
- TDD Framework (For .Net : NUnit, xUnit, MbUnit)
- Test Runner
- Ability to reverse engineer
Conclusion
As you see above, all these methodologies are alive and well in my development ecosystem and they all play overlapping roles. The thing to keep in mind is that there isn’t a point where I say “I am going to do BDD now!” or “It’s time for some DDD!” These methodologies are applied fluidly but precisely. I cannot stress enough that self discipline is at the foundation of any methodology you use. If you don’t believe enough in the methodology to follow it’s main tenants, then you’ll find yourself undermining your own efforts. At the end of the day, a methodology is a system, a series of steps that you take to develop an application; respecting that system can yield great results.
Aqua Bird AutoMocking Magic
0If you use any kind of mocking framework then this post is for you. If you don’t use a mocking framework, then I suggest you read this post anyways; it might make you see the light. In this post, I will show you how to utilize classes written by us here at Aqua Bird Consulting to trim your unit tests. There are some requirements that your code has to meet before you start using these awesome classes. You will see these requirements below. You probably already follow these conventions.
- You will need Moq (a mocking framework) or you may modify the code to use another framework like RhinoMocks.
- All classes that will be tested have to have all dependencies injected through the constructor.
- All mocked objects must abide by the rules of the mocking framework. i.e. The dependency implements a specific interface or methods/properties of an object to be mocked are marked virtual.
These are three simple rules, nothing to it really. Let’s take a look at what the test will look like before and after using these Aqua Bird classes. The example below is for a simple contact controller implemented in an Asp.Net MVC web application; we use NUnit at Aqua Bird Consulting.
Here is the before:
public void ContactController_Contact_Sends_An_Email()
{
// Create Mocks
var contactMock = new Mock<ContactSettings>();
var emailMock = new Mock<IEmailService>();
contactMock.SetupGet(s => s.ToAddress).Returns("test@test.com").Verifiable();
emailMock.Setup(e => e.Send(It.IsAny<MailMessage>())).Returns(true).Verifiable();
// Inject Mocks
var controller = new ContactController(emailMock.Object, contactMock.Object);
var viewResult = controller.Index(new ContactMessage()
{
Name = "Test",
Email = "test@test.com",
Text = "Hey what's up",
Subject = "hey"
}) as ViewResult;
Assert.IsNotNull(viewResult);
Assert.IsInstanceOf<ContactViewModel>(viewResult.ViewData.Model);
Assert.IsNotNull(viewResult.ViewData.Model);
// Verify Each Mock
contactMock.VerifyAll();
emailMock.VerifyAll();
}
Here is the after:
public void ContactController_Contact_Sends_An_Email()
{
var mock = new MockController<ContactController>();
mock.Mock<ContactSettings>().SetupGet(s => s.ToAddress).Returns("test@test.com").Verifiable();
mock.Mock<IEmailService>().Setup(e => e.Send(It.IsAny<MailMessage>())).Returns(true).Verifiable();
var viewResult = mock.Controller.Index( new ContactMessage()
{
Name = "Test",
Email = "test@test.com",
Text = "Hey what's up",
Subject = "hey"
} ) as ViewResult;
Assert.IsNotNull(viewResult);
Assert.IsInstanceOf<ContactViewModel>(viewResult.ViewData.Model);
Assert.IsNotNull(viewResult.ViewData.Model);
mock.VerifyAll();
}
You can see that in this one particular example we shaved four lines down to two. For a simple class it doesn’t seem very helpful, but with more complex classes that take several dependencies it can save a lot of time and typing. The thing you might have noticed in the example contact controller example is that we mocked both an interface and an object. So how does this all work?
Let me first start by explaining what the automocking class does on a high level.
- When you initialize a new automock class we first look at the constructor, and retrieve the most complex one (most parameters).
- we then get all parameters to this constructor and we begin to create the mocks
- As we create the mocks we place them into a dictionary
- After all the mocks are created, we create the instance of the class to be tested
- Let the testing begin!!!
/// <summary>
/// Will create the mocks and inject a newly created object of type T
/// only supports constructor based injection
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class MockObject<T>
{
/// <summary>
/// Dictionary that holds all the mocks
/// </summary>
private readonly Dictionary<Type, Mock> _mocks;
/// <summary>
/// Initializes a new instance of the <see cref="MockController<T>"/> class.
/// </summary>
protected MockObject()
{
_mocks = new Dictionary<Type, Mock>();
InitializeMocksAndObject();
}
/// <summary>
/// Gets the controller.
/// </summary>
/// <value>The controller.</value>
protected T Target { get; set; }
/// <summary>
/// Initializes the mock dictionary and controller.
/// </summary>
protected void InitializeMocksAndObject()
{
Type controllerType = typeof (T);
ParameterInfo[] parameterInfo = null;
ConstructorInfo constructor = null;
// Go through the constructors and find the most
// complex one, if things are right (one constructor)
// then this should go through once
foreach (ConstructorInfo c in controllerType.GetConstructors())
{
ParameterInfo[] temp = c.GetParameters();
if (parameterInfo != null && temp.Count() <= parameterInfo.Count())
continue;
constructor = c;
parameterInfo = temp;
}
// Now that we have are most complex constructor
// we know what types we need to call
if (parameterInfo != null)
foreach (ParameterInfo info in parameterInfo)
{
// Have to call register type through reflection
// just the nature of the beast
MethodInfo method = typeof (MockObject<T>).GetMethod("RegisterType",
BindingFlags.Instance | BindingFlags.NonPublic);
MethodInfo generic = method.MakeGenericMethod(info.ParameterType);
generic.Invoke(this, null);
}
// Create The Controller
var parameters = new List<object>();
foreach (Mock mock in _mocks.Values.ToArray())
parameters.Add(mock.Object);
Target = constructor != null ? (T)constructor.Invoke(parameters.ToArray()) : default(T);
}
/// <summary>
/// Mocks this instance.
/// </summary>
/// <typeparam name="TMockType">The type of the mock type.</typeparam>
/// <returns></returns>
public Mock<TMockType> Mock<TMockType>()
where TMockType : class
{
return _mocks[typeof (TMockType)] as Mock<TMockType>;
}
/// <summary>
/// Registers the type.
/// </summary>
/// <typeparam name="TMockType">The type of the mock type.</typeparam>
protected void RegisterType<TMockType>()
where TMockType : class
{
var mock = new Mock<TMockType>();
_mocks.Add(typeof (TMockType), mock);
}
public void VerifyAll()
{
foreach (var mock in _mocks)
mock.Value.VerifyAll();
}
}
There it is. This is the abstract base class that performs the majority of the work, mocking up objects and placing them in a dictionary. In the example with the contact controller, I inherited from the MockObject base class and created a sub class with a property called “Controller” so that my tests read better. You can follow this convention to create more readable tests.
/// <summary>
/// Using the Moq Framework this will create all
/// the mocks and the controller (only supports constructor based DI)
/// </summary>
/// <typeparam name="T"></typeparam>
public class MockController<T> : MockObject<T>
where T : IController
{
public T Controller
{
get { return Target; }
}
}
So there you have it, if you would like to run an example of the automocking class, I have included a sample project below with all the files and dependencies you’ll need to get started. Feel free to modify the code and make any changes you feel necessary.
Thanks,
Khalid Abuhakmeh
