Andreas Aschauer studied Software Engineering at Vienna Technical University. Besides his studies he worked as a developer and consultant for .NET framework based solutions for various international corporations. Since 2009 he is a Development Trainer at ppedv GmbH with a strong focus on ASP.NET and SharePoint classroom courses. As the founder and co-owner of CodeForce he develops and consults real world SharePoint Solutions. As an active blogger for the Microsoft Developer & Platform Group and as a speaker on numerous conferences he shares is expertise on SharePoint and classical Software Engineering Processes / Practices.
The Article was written and translated to English by Andreas Aschauer, was published originally at
Andreas Rudolf Aschauer, BSc.
Test-Driven-Development with Sharepoint 2010
Adhering to the principles of clean Software Design is not always an easy task. Using and understanding how to apply Software Engineering Principles to real world projects makes the difference between a programmer and a Software Engineer.
The Microsoft SharePoint Platform and its API’s introduce a new challenge for developers building solutions on top of it. Creating loosely coupled, testable components for SharePoint is a non- trivial task. Most software relies on the existence of a physical SharePoint Farm, which stands in sharp contrast to the goals of Clean-Code Development.
Test-Driven-Development
Let us first take a look at TDD in general and who it is done, before examining the special challenges introduced with TDD on SharePoint.
Test-Driven-Development is an iterative process. Contrary to a legacy approach where production code comes first and is then validated by Unit Tests, the Unit Tests in a TDD style development process always come first! The tests reflect the specification and the assertions made, express the expectations we have, when the system is in a given context.
The whole iterative development process is known as Red- Green- Refactor Cycle. See fig. 1
– Red: Starting with a test, the test is red, because the production code doesn’t even exist
– Green: From developing the test, it is clear what classes, fields and methods are required to satisfy the test. Production code is implemented until the test is green. Only the minimal implementation that turns the Unit Test to green shall be produced! No overhead code.
– Refactor: After the expectations, expressed through the test have been met by the code, it is time to refactor and apply the “Software Engineering Principles” (see Box).
Software Engineering Principles
DRY, YAGNI, KISS… do those acronyms sound a bell? They are the ground rules for good software design. Don’t Repeat Yourself, You Ain’t Gonna Need It, Keep It Simple and Safe – with all these principles in mind source code becomes cleaner, better maintainable and that implicitly leads to higher quality. Take a look at some code from one of your past projects and you will see – There’s always work to be done!
Scanning your code for the violation of the Software Engineering Principles is an important step in Test-Driven-Development and – besides the Unit Tests themselves – the most important mean to improve software architecture.
The beauty of TDD lies in the fact that all code is instantly validated against the specification by the Unit Tests. Also the design – the architecture – is greatly influenced by this programming style. Everything tightly coupled or tied to external systems cannot be tested and thus has to be reengineered. Because we always start with the tests, we get an “external” view on the system to be developed and its components. From the very beginning on, the developer has to create a good, loosely coupled design, to be able to separate the various “modules” and test them isolated. To achieve that, programming against Interfaces – not concrete implementations – is the right way.
Test-Driven-Development with Sharepoint
Removing dependencies on external systems is one of the greatest challenges in Test-Driven-Development. Simulating systems and objects is known as Mocking or Stubbing.
Every developer who has already worked with the SharePoint Object Model knows how tightly coupled custom code is with the underlying SharePoint infrastructure. Even the most basic code, is intrinsically tied to an external system – SharePoint in this case. Take a look at the following extremely simple code snippet, which in most cases is the “entry point” into the object model.
public static SPSite GetSiteCollection(string url)
{
//Entweder explizit
return new SPSite(url);
//Oder via SPContext bei WebParts etc.
return SPContext.Current.Site;
}
This simple method call is enough hardwire our code to an external dependency and wipe out the possibility of context-agnostic, automated testing. As SPSite does not implement any interface, it is also nearly impossible (only with great, time- consuming effort) to mock this dependency. Using a Mocking- Framework is the only feasible way to develop TDD-style with SharePoint.
Typemock Isolator for SharePoint provides the functionality needed for SharePoint developers to conduct serious Unit-Testing and develop high quality production code. Recommended by Microsoft Patterns & Practices it is the framework of choice for the task at hands.
Typemock Isolator for SharePoint can swap instances of objects at run-time. The framework substitutes real instances of SharePoint objects for mocked instances, whose behavior and return values can be defined in many ways. With Typemock Isolator in the toolbox it is possible to conduct real Test-Driven Development. We are able to run Unit Tests separated from a real SharePoint system. More important; we can now also create a System-Under-Test in memory. Unit Tests should never rely on any context created by another test and should always create and tear down the context needed for the assertions to be done.
Let’s take a look at a simple demo to learn about the “TDD development-flow” and the how to leverage Typemock Isolator for SharePoint development in C#.
Sample Scenario
The sample is intentionally kept simple to showcase the steps. The following tasks needs to be done:
A SharePoint list is filled with data from an import run. The list contains a (Text) field with an E-Mail address. Whenever a new item is created through import, an email should be sent to the E-Mail address.
To react to the list event a List Item Event Receiver can be used, that fires when a new item is created.
To create an Event Receiver select File -> New Project and chose the Event Receiver Template from the SharePoint tab. In the following wizard select “Sandboxed Solution” as a deployment type and choose the list template for the event receiver. For the sample choose “Task List” as list template and “An Item was Added” as the event type.
We want to develop TDD-style, so we add another class library project to our solution which will host the test code. To be able to work with Typemock Isolator, add a reference to Typemock. Arrange Act Assert.dll to the test project. Figure 3 shows the solutions structure.
Now it’s time to start implementing the specification, consisting of three methods.
1.) Parse the email address from the list element
2.) Validate the email address format
3.) Send the email
That means, we write the first unit test, that expresses the context in which the system is and our expectations about the behavior.
public class When_a_new_task_is_created
{
[Test]
public void Then_the_email_address_field_should_be_parsed_for_an_adress()
{}
}
The class and method names might seem a little unusual; they follow the idea of Behavior-Driven-Development. (see Box)
Behavior Driven Development
Behavior Driven is a way of naming test cases and classes in natural language. That way, when looking at the results of a test run, it becomes clear, from the names of the tests what functionality a test validates.
The names of the test classes express the context or situation and the test cases express the desired behavior.
Our first test is a structural one. It validates whether the method that parses out the email address from the list element called at all. That seems trivial in the sample, but when developing with a Dependency Injection Container it becomes important to verify whether the right methods of the right instances have been called.
Purists would now implement the whole test and only then derive the classes and methods needed in the production code from the test. For sake of article length we assume the code is already there.
public override void ItemAdded(SPItemEventProperties properties)
{
try
{
var emailAddress =
GetEmailAddress(properties);
}
catch (Exception ex)
{
properties.ErrorMessage = ex.Message;
properties.Cancel = true;
properties.Status = SPEventReceiverStatus.CancelWithError;
}
}
public string GetEmailAddress(SPItemEventProperties properties)
{
try
{
var address =
properties.ListItem.GetFormattedValue(emailFieldName);
return address;
}
catch (Exception)
{
throw new ArgumentException
(“Field ‘” + emailFieldName + “‘ not found in list”);
}
}
From the code snippet it becomes clear that isolating an testing GetEmailAddress(..) is not trivial. We have a dependency on SPItemEventProperties. To simulate this „external system“ we can now use Typemock Isolator. Using a fluent, intuitive syntax we can fake a complete instance using the generic call Isolate.Fake.Instance<SPItemEventProperties>(). To control the behavior and mock method return wird Isolate.WhenCalled(..) can be used which accepts a Lambda Expression as an argument. To verify if a method has been called on our mock object Typemock Isolator providesIsolate.Verify(..) which also represents the assertion for our testing framework.This is all that is needed for our test to be readily implemented.
[Test]
public void Then_the_email_address_field_should_be_parsed_for_an_adress()
{
//Arrange
_receiver =
Isolate
.Fake.Instance<TaskListMailerEventReceiver>(Members.CallOriginal);
_fakeSpItemEventProperties =
Isolate.Fake.Instance<SPItemEventProperties>();
Isolate.WhenCalled(
() => _fakeSpItemEventProperties
.ListItem.GetFormattedValue(„Email Adress“))
.WillReturn(„office@codeforce.at“);
//Act
_receiver.ItemAdded(_fakeSpItemEventProperties);
//Assert
Isolate.Verify.WasCalledWithArguments(
() => _receiver.GetEmailAddress(“”, null))
.Matching(args => (args[0] == _fakeSpItemEventProperties));
}
First we create a mocked instance of the ItemEventReceiver and specify that all calls should be routed to the original implementations. The behavior for the mock of SPListItemEventProperties is determinded with Isolate.WhenCalled(..). In this case GetFormattedValue(“Email Address”) should return “office@codeforce.at“. Now we have completed stripped out the dependency on SharePoint and this Unit Test can run separately on a Continuous Integration Server.
The assertion is done afterwards an verifies that the method was called with the exact arguments passed in by the EventReceiver in the event handler. This is done with a call to .Matching(..) that accepts a lambda expression to check the args[].
An common task when working with SharePoint lists and list fields is the error handling logic around missing fields or misspelled field names. The following code snippet shows how to raise an exception and validate if the correct error handling in the ItemAdded(..) event handler.
[Test]
public void Then_an_exception_should_occur_when_adress_field_is_malformed()
{
//Act
Isolate.WhenCalled(
() => _fakeSpItemEventProperties
.ListItem.GetFormattedValue(EmailAddressFieldName))
.WillThrow(new System.ArgumentException());
_receiver.ItemAdded(_fakeSpItemEventProperties);
//Assert
Assert.That(_fakeSpItemEventProperties.Cancel == true);
}
The method WillThrow(..) ensures that the call to GetFormattedValue(..) throws an ArgumentException, which is exactly what will happen in the real system when the field is missing or misspelled.
The validation of the email address format is part of this article as this can be easily tested without mocking, there is no external dependency involved.
The third issue however is interesting in terms of mocking. Sending an email is done via a static class called SPUtility. Typemock Isolator supports faking static classes and methods via Isolate.Fake.StaticMethods(..). If the class itself is static (ie. not only the methods) the static constructor must also be faked with Isolate.Fake.StaticConstructor(..).
The following unit test shows how to fake a static class and a static method call and validate if the static call was made with any arguments g
[Test]
public void Then_an_email_is_sent()
{
//Arrange
//Fake static SPUtility
Isolate.Fake.StaticConstructor(typeof(SPUtility));
Isolate.Fake.StaticMethods(typeof(SPUtility), Members.CallOriginal);
Isolate.WhenCalled(
() => _fakeSpItemEventProperties
.ListItem.GetFormattedValue(EmailAddressFieldName))
.WillReturn(„office@codeforce.at“);
//Act
_receiver.ItemAdded(_fakeSpItemEventProperties);
//Assert
Isolate.Verify.WasCalledWithAnyArguments(
() => SPUtility.SendEmail(_fakeWeb, false, false, EmailAdress, “Test”, “”));
}
Further capabilities
Typemock Isolator also allows to automatically swap all future instances of a class with a fake with
Isolate.Swap.AllInstances<SPWeb>().With(Isolate.Fake.Instance<SPWeb>()). Furthermore Isolator can be used to fake private Methods. There is no need to make private methods visible to other assemblies, Isolator can find them via Reflection.
Typemock Isolator can do a lot of things and the full version also is not limited to the SharePoint Object Model but can be universally used across every .NET Assembly.
Download Typemock Isolator Now: Get a 15-day FREE trial of Typemock Isolator Complete – and Typemock Isolator Basic will remain yours once the trial period is over!