TDD Process Outside-In? - asp.net-mvc

Lets assume I've created the following test for my sample blog app:
[TestClass]
public class when_the_blog_controller_index_action_executes : BlogControllerTests
{
//...
[TestMethod]
[TestCategory("BlogController")]
public void it_should_pass_the_latest_blogentries_to_the_view()
{
blogs = new List<BlogEntry>() { new BlogEntry("title1", "b1"), new BlogEntry("title2", "b2"), new BlogEntry("title3", "b3") };
blogServiceMock = new Mock<IBlogService>();
blogServiceMock.Setup(s => s.GetLatestBlogEntries())
.Returns(blogs);
var controller = new BlogController(blogServiceMock.Object);
var model = ((ViewResult)controller.Index()).Model as IEnumerable<BlogEntry>;
Assert.IsTrue(blogs.SequenceEqual(model));
blogServiceMock.VerifyAll();
}
}
After the BlogController implementation, I have a running test:
public class BlogController : Controller
{
IBlogService blogService;
public BlogController(IBlogService blogService)
{
this.blogService = blogService;
}
public ActionResult Index()
{
var model = blogService.GetLatestBlogEntries();
return View(model);
}
}
So what is the next step? Should I create the implementation for the IBlogService (with test) and after create the repository (with test)?
If I'd have a service like this, basically i wouldn't test anything, because I'd just mocking the repository...
public class BlogService : IBlogService
{
IBlogRepository blogRepository;
public BlogService(IBlogRepository blogRepository)
{
this.blogRepository = blogRepository;
}
public IEnumerable<BlogEntry> GetLatestBlogEntries()
{
return blogRepository.GetLatestBlogEntries();
}
}

The next step is to unit test the BlogService implementation you have written. In this test you should ensure that the proper methods are being called on a mocked repository. If later your service logic evolves and you have some methods that perform more than just CRUD repository access your test will start to make more sense.
Your current implementation of this service simply delegates the calls to the repository and that's what you should unit test.
And if you find yourself having your service layer consist of simple CRUD methods that are doing nothing more than delegating the call to some repository maybe you should ask yourself on the usefulness of this service layer and whether it wouldn't be also possible to directly use the repository from the controller.

> TDD Process Outside-In?
I would use both a mix of outside-in (BDD) and inside out (TDD) in two nested loops as described in Behavior-Driven Development with SpecFlow and WatiN
* writing a failing (outside-in) integration tests
* writing a failing (inside out) unit test as part of the solution of the integration test
* making the unittest pass
* refactor
* writing the next failing unit test as part of the integration test
* unitl the integration test passes
* writing the next failing integration tests

Related

Unit test wiring of MVC, FluentValidation, and Ninject

I have set up an MVC web project with FluentValidation and Ninject using the Ninject.Extensions.Mvc.FluentValidation package. I followed the documentation of that package directly.
I'd like to write an automated test that verifies this wiring, and checks that the model validation will use the FluentValidation validators as expected. I'm having a hard time spinning up the right pieces of the MVC application in my test in order to do this.
Basically, I want to spin up the MVC app enough so that the Ninject kernel is created, the model binders are wired, and validators are created. Then I want to try to validate an entity through the MVC model validation and make sure that expected messages from the validator are showing up.
What is the best way to automating the testing of the interaction between Ninject, MVC, and FluentValidation?
I have similar setup but I use Unity instead of Ninject.
My IoC container inherits UnityContainer where I register all my repos, validarots, etc. I benefit from this because I have validators with repo dependencies (e.g. UserRegistrationValidator checks for unique user names).
My IoC container also implements IValidatorFactory. I use it register a global ModelValidatorProvider like this:
var ioc = new IoCContainer();
ModelValidatorProviders.Providers.Add(new FluentValidationModelValidatorProvider(ioc));
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
With this setup I know that my validators will intercept model validation in controller actions but only if validators are resolved by ValidatorFactory.
So basically I have 2 groups of tests
- IoC tests
With these I test if my IoC container can resolve a validator for a model. With Unity it looks something like this:
// Arrange
var ioc = new IoCContainer();
// Assert
Assert.IsTrue(ioc.IsRegistered(IValidator<MyModel>));
If you have all your models under one namespace you could even write a single unit test by getting all types from specific namespace and check if IValidator is registered for them in a loop.
- Validator tests
These are common tests to test my (view)models:
// Arrange
var validator = new MyModelValidator();
var model = new MyModel{ Name = null };
// Assert
validator.ShouldHaveValidationErrorFor(x => x.Name, model)
With this there is no need to spin application, you just test what you create.
Hope this helps.
What we use here for the integration test is Selenium Webdriver, you can get it with NuGet. We write code usign page pattern so it's easyer to maintain.
When I want to check if a requiered field or any other custom validation I do the following :
[TestFixture]
public class CenterTests : TestBase
{
[Test]
public void CreateViewAndEditShouldWork()
{
S.OpenWithCI();
var loginPage = new LoginPage(S);
var homePage = loginPage.LoginValidUser("email", "Password");
var centerListPage = homePage.ClickCenterAndRoomLink();
var centerPage = centerListPage.ClickCreateLink();
//Create
centerPage.CreateInvalidCenter();
Assert.That(S.FindElement(By.CssSelector("span[for=Name]")).Text, Is.StringContaining(Strings.Error_Required));
Assert.That(S.FindElement(By.CssSelector("span[for=EnglishName]")).Text, Is.StringContaining(Strings.Error_Required));
centerListPage = centerPage.CreateValidCenter("Saguenay", "Sag", "2089 blv Talbot");
Thread.Sleep(2000);
S.ExpectSuccessNotice(Strings.CenterCreatedSuccessfully);
}
}
And here's the code of my TestBase helper class :
namespace Afi.AutomatedTests.Helpers
{
[TestFixture]
public class TestBase
{
protected IWebDriver S;
[SetUp]
public virtual void TestSetup()
{
S = new ChromeDriver();
S.Manage().Window.Size = new Size(1024, 768);
S.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
}
[TearDown]
public void TearDown()
{
S.Quit();
}
public string GetUrl(string relativePath)
{
if(!relativePath.StartsWith("/"))
throw new ArgumentException("Relative URL must begins with /");
return "http://afi.local" + relativePath;
}
}
}
All those tests are in an other project call AutomatedTests and I can run them the same way I run unit test (resharper/nunit). It uses Chromedriver to do the tests.
Let me know if you need more informations.

How to Unit/Integrate Test Views to detect breaking changes

I have just started learning asp.net mvc and one reason of the primary reasons has been to move to TDD.
I am writing a small dashboard application which has reports. In this app, I had a primary controller called ReportsController, which right now has just one method, GetReport that takes in a query and returns a view if the query meets certain conditions, else returns an error message.
[HttpGet]
public ActionResult GetReport(string query)
{
//calls the QueueRep and gets back DataTable
ReportQuery reportQuery = new ReportQuery(query);
if (reportQuery.IsValidQuery)
{
queryRepository.ExecuteReportQuery(ref reportQuery);
}
else
{
return View("Error");
}
ViewData.Add("ResultDataTable",reportQuery.ResultDataTable);
return View();
}
I had written 2 unit tests for this as follows
public void GetReport_Should_Return_Error_View_For_Malicious_Query()
{
//Arrange
string query = "drop table userInfo";
var controller = CreateReportsController(query);
//Act
var result = controller.GetReport(query) as ViewResult;
//Assert
Assert.AreEqual(result.ViewName, "Error");
}
[Test]
public void GetReport_Should_Return_View_With_DataTable_For_Correct_Query()
{
//Arrange
StringBuilder sb = new StringBuilder();
sb.Append("SELECT Year(CreatedOn) as Year, Month(CreatedOn) as Month, Count(CREATEDON) as NewEmployers");
sb.Append("FROM dbo.UserInfo WHERE DefaultPurpose = 1 GROUP BY Year(CreatedOn), Month(CreatedOn)");
string query = sb.ToString();
var controller = CreateReportsController(query);
//Act
var result = controller.GetReport(query) as ViewResult;
//Assert
Assert.IsTrue(result.ViewData.ContainsKey("ResultDataTable"));
Assert.IsTrue(result.ViewData["ResultDataTable"].GetType() == typeof(System.Data.DataTable));
}
Now, due to conflict with SSRS, the server/Reports was pointing to SSRS instead of Reports controller so I changed name of ReportsController to MyReportsController. I used refactor for the name change and changed my unit tests in the test project as well and ran the unit tests. Everything is fine.
But now when I ran actual app, I got an error. Basically, the folder name of the views had to be changed from Reports to MyReports. How can I test these kind of scenarios. Is only using functional testing tools like selenium? Or I could have written my tests differently?
I don't think there is anything you should/could do to test this with unit tests, but integration tests with Selenium is a good way to go about it:
http://seleniumtoolkit.codeplex.com/
Yes, manual testing or functional test tools like Selenium are the only way to find these breaking changes.
The reason is because with unit testing you are only testing small bite sized parts of your code. So testing a controller's action method is great! In that test you need to remember that your testing your own code and not the asp.net and/or mvc frameworks. Now, to -render- a view result, this is handled outside of your action method. Secondly, we assume that the rendering logic (how to render) has been tested by Microsoft so we don't want waste time testing that either.
So this means we need to join independent modules together in a single test. When we have 2+ modules or areas etc to test, we suddenly jump out of unit testing and into manual or functional testing.

How to test Ninject ConstructorArguments using MOQ objects?

I have been doing my first Test Driven Development project recently and have been learning Ninject and MOQ. This is my first attempt at all this. I've found the TDD approach has been thought provoking, and Ninject and MOQ have been great. The project I am working on has not particularly been the best fit for Ninject as it is a highly configurable C# program that is designed to test the use of a web service interface.
I have broken it up into modules and have interfaces all over the shop, but I am still finding that I am having to use lots of constructor arguments when getting an implementation of a service from the Ninject kernel. For example;
In my Ninject module;
Bind<IDirEnum>().To<DirEnum>()
My DirEnum class;
public class DirEnum : IDirEnum
{
public DirEnum(string filePath, string fileFilter,
bool includeSubDirs)
{
....
In my Configurator class (this is the main entry point) that hooks all the services together;
class Configurator
{
public ConfigureServices(string[] args)
{
ArgParser argParser = new ArgParser(args);
IDirEnum dirEnum = kernel.Get<IDirEnum>(
new ConstructorArgument("filePath", argParser.filePath),
new ConstructorArgument("fileFilter", argParser.fileFilter),
new ConstructorArgument("includeSubDirs", argParser.subDirs)
);
filePath, fileFilter and includeSubDirs are command line options to the program. So far so good. However, being a conscientious kind of guy, I have a test covering this bit of code. I'd like to use a MOQ object. I have created a Ninject module for my tests;
public class TestNinjectModule : NinjectModule
{
internal IDirEnum mockDirEnum {set;get};
Bind<IDirEnum>().ToConstant(mockDirEnum);
}
And in my test I use it like this;
[TestMethod]
public void Test()
{
// Arrange
TestNinjectModule testmodule = new TestNinjectModule();
Mock<IDirEnum> mockDirEnum = new Mock<IDirEnum>();
testModule.mockDirEnum = mockDirEnum;
// Act
Configurator configurator = new Configurator();
configurator.ConfigureServices();
// Assert
here lies my problem! How do I test what values were passed to the
constructor arguments???
So the above shows my problem. How can I test what arguments were passed to the ConstructorArguments of the mock object? My guess is that Ninject is dispensing of the ConstuctorArguments in this case as the Bind does not require them? Can I test this with a MOQ object or do I need to hand code a mock object that implements DirEnum and accepts and 'records' the constructor arguments?
n.b. this code is 'example' code, i.e. I have not reproduced my code verbatim, but I think I have expressed enough to hopefully convey the issues? If you need more context, please ask!
Thanks for looking. Be gentle, this is my first time ;-)
Jim
There are a few problems with the way you designed your application. First of all, you are calling the Ninject kernel directly from within your code. This is called the Service Locator pattern and it is considered an anti-pattern. It makes testing your application much harder and you are already experiencing this. You are trying to mock the Ninject container in your unit test, which complicates things tremendously.
Next, you are injecting primitive types (string, bool) in the constructor of your DirEnum type. I like how MNrydengren states it in the comments:
take "compile-time" dependencies
through constructor parameters and
"run-time" dependencies through method
parameters
It's hard for me to guess what that class should do, but since you are injecting these variables that change at run-time into the DirEnum constructor, you end up with a hard to test application.
There are multiple ways to fix this. Two that come in mind are the use of method injection and the use of a factory. Which one is feasible is up to you.
Using method injection, your Configurator class will look like this:
class Configurator
{
private readonly IDirEnum dirEnum;
// Injecting IDirEnum through the constructor
public Configurator(IDirEnum dirEnum)
{
this.dirEnum = dirEnum;
}
public ConfigureServices(string[] args)
{
var parser = new ArgParser(args);
// Inject the arguments into a method
this.dirEnum.SomeOperation(
argParser.filePath
argParser.fileFilter
argParser.subDirs);
}
}
Using a factory, you would need to define a factory that knows how to create new IDirEnum types:
interface IDirEnumFactory
{
IDirEnum CreateDirEnum(string filePath, string fileFilter,
bool includeSubDirs);
}
Your Configuration class can now depend on the IDirEnumFactory interface:
class Configurator
{
private readonly IDirEnumFactory dirFactory;
// Injecting the factory through the constructor
public Configurator(IDirEnumFactory dirFactory)
{
this.dirFactory = dirFactory;
}
public ConfigureServices(string[] args)
{
var parser = new ArgParser(args);
// Creating a new IDirEnum using the factory
var dirEnum = this.dirFactory.CreateDirEnum(
parser.filePath
parser.fileFilter
parser.subDirs);
}
}
See how in both examples the dependencies get injected into the Configurator class. This is called the Dependency Injection pattern, opposed to the Service Locator pattern, where the Configurator asks for its dependencies by calling into the Ninject kernel.
Now, since your Configurator is completely free from any IoC container what so ever, you can now easily test this class, by injecting a mocked version of the dependency it expects.
What is left is to configure the Ninject container in the top of your application (in DI terminology: the composition root). With the method injection example, your container configuration would stay the same, with the factory example, you will need to replace the Bind<IDirEnum>().To<DirEnum>() line with something as follows:
public static void Bootstrap()
{
kernel.Bind<IDirEnumFactory>().To<DirEnumFactory>();
}
Of course, you will need to create the DirEnumFactory:
class DirEnumFactory : IDirEnumFactory
{
IDirEnum CreateDirEnum(string filePath, string fileFilter,
bool includeSubDirs)
{
return new DirEnum(filePath, fileFilter, includeSubDirs);
}
}
WARNING: Do note that factory abstractions are in most cases not the best design, as explained here.
The last thing you need to do is to create a new Configurator instance. You can simply do this as follows:
public static Configurator CreateConfigurator()
{
return kernel.Get<Configurator>();
}
public static void Main(string[] args)
{
Bootstrap():
var configurator = CreateConfigurator();
configurator.ConfigureServices(args);
}
Here we call the kernel. Although calling the container directly should be prevented, there will always at least be one place in your application where you call the container, simply because it must wire everything up. However, we try to minimize the number of times the container is called directly, because it improves -among other things- the testability of our code.
See how I didn't really answer your question, but showed a way to work around the problem very effectively.
You might still want to test your DI configuration. That's very valid IMO. I do this in my applications. But for this, you often don't need the DI container, or even if your do, this doesn't mean that all your tests should have a dependency on the container. This relationship should only exist for the tests that test the DI configuration itself. Here is a test:
[TestMethod]
public void DependencyConfiguration_IsConfiguredCorrectly()
{
// Arrange
Program.Bootstrap();
// Act
var configurator = Program.CreateConfigurator();
// Assert
Assert.IsNotNull(configurator);
}
This test indirectly depends on Ninject and it will fail when Ninject is not able to construct a new Configurator instance. When you keep your constructors clean from any logic and only use it for storing the taken dependencies in private fields, you can run this, without the risk of calling out to a database, web service or what so ever.
I hope this helps.

Grails - save() failing with MissingMethodExcepition in integration test

I'm learning groovy / grails, and writing my first integration test.
It's currently failing with:
groovy.lang.MissingMethodException: No
signature of method:
com.mangofactory.scurry.User.save() is
applicable for argument types: ()
values: []
My test isn't doing anything fancy:
class UserEventControllerTests extends ControllerUnitTestCase {
protected void setUp() {
super.setUp()
}
protected void tearDown() {
super.tearDown()
}
void testAddingAUser()
{
def user = new User(emailAddress: "martypitt#test.com")
user.save()
}
}
Saving the entity works fine when I do it through the scaffolded pages provided by grails.
What have I missed?
If you want it to be an integration tests it shouldn't extend one of the unit test base classes, so change it to
class UserEventControllerTests extends GroovyTestCase {
...
}
and make sure it's in test/integration, not test/unit.
But it looks like you want to test a controller (it's called UserEventControllerTests) which should extend ControllerUnitTestCase. If that's the case then you should be doing unit tests, but mocking the domain layer (using mockDomain and others) since you want to focus on controller logic, not persistence. Test domain classes in proper integration tests using a database.
This is all described in chapter 10 of the docs: http://grails.org/doc/latest/

EF4 Repository Pattern problems injecting repository into service .Cannot seem to get it right

I am finding difficult to test EntityFramework 4 .I am using it using the database first approach,too late now to move to poco.Needed to deliver pretty quickly,no time to learn properly as usual.
I have implemented the repository pattern with unit of work but I am finding difficult to inject a repository into my Service layer so that I can test the behaviour of my business layer service ,validation etc... without hitting the db.
but I am incurring in many little problems.
In order to inject the Repository into the service(constructor) the calling layer need to have a reference to the DAL (EF Entities) . I dont want this
If i have many repositories EG CustomerRepository ,EmployeeRepository than I need to have as many constructors as repositories so that I can inject the repository.
3.Not sure where to go from here. I have not found any example on the net where they inject the repository into the service using EF4. All the examples I have seen they mock the repository on it's own,which is not good to me.
I need to test my service layer/BizLayer without hitting the database.
The all thing is just not testable and adds so many dependencies and problems.
Noddy example I have put together
public class DepartmentServiceLibrary
{
private readonly IDepartmentRepository _departmentRepository;
public DepartmentServiceLibrary(IDepartmentRepository departmentRepository)
{
_departmentRepository = departmentRepository;
}
public List<DepartmentDto> GetDepartments()
{
return DeparmentBiz.GetDepartments();
}
private DeparmentBL _departmentBiz;
private DeparmentBL DeparmentBiz
{
get
{
return _departmentBiz ?? new DeparmentBL(_departmentRepository);
}
}
}
//internal class
internal class DeparmentBL
{
private readonly IDepartmentRepository _departmentRepository;
public DeparmentBL(IDepartmentRepository departmentRepository)
{
_departmentRepository = departmentRepository;
}
public List<DepartmentDto> GetDepartments()
{
using (var ctx = new AdventureWorksContext())
{
var uow = new UnitOfWork(ctx);
_departmentRepository.UnitOfWork = uow;
var query = _departmentRepository.GetAll();
return query.Select(dpt => new DepartmentDto
{
DepartmentId = dpt.DepartmentID,
Name = dpt.Name,
GroupName = dpt.GroupName
}).ToList();
}
}
}
The following TestMethod requires me to add a ref to the dal which defeats the point
[TestMethod]
public void Should_be_able_to_call_get_departments()
{
var mock = new Mock<IDepartmentRepository>();
var expectedResult = new List<Department>(); //Dependency to DAL as Department is a EF Entity generated by EF.
mock.Setup(x => x.GetAll()).Returns(expectedResult);
var companyService = new MyCompanyBL(mock.Object); //InternalVisibileTO
var departments = companyService.GetAll();
//assert removed for brevity
Any suggestions or examples out there that shows how to do it?
thanks
}
The short answer is - since you're not using POCOs, all your layers will have a reference to your DAL.
Without POCOs, you use code generation, which means EF creates the model classes in the Model.edmx.designer.cs file.
An option (haven't tried this - off the top of my head) is to manually project the EF entities into DTOs.
So your Repository might do this:
public List<OrderDTO> GetOrdersForCustomer(int customerId)
{
return _ctx.Orders
.Where(x => x.CustomerId == customerId)
.ToList()
.Select(x => new OrderDTO { // left to right copy });
}
The OrderDTO class could be in a separate assembly, which the repository references, as well as your other projects. So the other projects would work off the DTO assembly, and wouldn't require a reference to the Repository.
But here you're projecting into classes everywhere (basically doing POCO, but manually, and with more work) left to right copying of properties - very painful.
However, that is an option.
Honestly - it does not take long to move to POCOs.
There is a T4 template which will generate the POCOs for you - you could be up and running in a matter of minutes.
And since you're already using dependency injection and repository, you should either bite the bullet and change to POCOs, or keep the reference to the DAL.
Something similar in terms of code can be seen here in GitHub
and detail explanation can be found in TechNet

Resources