Story Details for articles

Golf Tracker - Ep. 5 - Service Layer and Unit Tests

kahanu
Author:
Version:
Views:
2985
Date Posted:
8/24/2011 7:49:50 PM
Date Updated:
8/24/2011 7:49:50 PM
Rating:
0/0 votes
Framework:
ASP.NET MVC 2
Platform:
Windows
Programming Language:
C#
Technologies:
NUnit
Tags:
golf, golf tracker, nunit
Demo site:
Home Page:
Share:

Golf Tracker - Service Layer and Unit Tests

Similar to the last episode where I built some simple unit tests for the CourseRepository, in this episode I'll test the service layer classes.

Again like previously I have a choice of whether to use a mocking framework like RhinoMocks, Moq, etc., or simply test against a fake repository.  And in this case since I'm testing the service layer which isn't directly connected to the data repositories, I can either test the service layer functionality directly, or do what I call "pass-through" testing, which will test against our existing fake repositories.  I will be choosing the latter.

Note: when I'm testing against data from a data source such as SQL Server, I prefer to create fake repositories as much as I can to test against.  This way I can really see if my queries are working and if my class structures are working.  If I'm building an API type of application, I may choose to mock the tests instead.  It all depends on the overall scenario.

What I'll do first is create a new class in the UnitTests project for the Course Service tests.

course service unit tests folder

Here's a look at the early version of the service class unit tests.

01.using System;
02.using GolfTracker.DataObjects.Interfaces;
03.using GolfTracker.Services;
04.using GolfTracker.UnitTests.Course_Tests;
05.using NUnit.Framework;
06.using NUnit.Framework.SyntaxHelpers;
07. 
08.namespace GolfTracker.UnitTests.Course_Service_Tests
09.{
10.    [TestFixture]
11.    public class CourseServiceTests
12.    {
13.        ICourseRepository GetRepository()
14.        {
15.            return new FakeCourseRepository(new FakeCourseData().GetCourses());
16.        }
17. 
18.        [Test]
19.        public void Course_Service_Returns_10_Courses()
20.        {
21.            var service = new CourseService();
22.            service.CourseRepository = GetRepository();
23. 
24.            var courses = service.GetAll();
25. 
26.            Assert.AreEqual(10, courses.Count);
27.        }
28. 
29.        [Test]
30.        public void Course_Name_For_GetById_Is_Course_5()
31.        {
32.            var service = new CourseService();
33.            service.CourseRepository = GetRepository();
34. 
35.            var course = service.GetById(new Guid("ed95e452-4675-4bc1-ba1b-9fce741ae51a"));
36. 
37.            Assert.AreEqual("Course 5", course.CourseName);
38.        }       
39.    }
40.}

As you can see these are very simple tests, and they should be.  Each unit test should be as small as possible and be written just to the point that it passes.

Each method first instantiates a new CourseService() class and then applies the dependency injection with the GetRepository() method.  At this point we can call any of the methods of the service class.  At first we want to make sure everything is working as it should so the tests will be very simple, but as I build the application they will most likely get more complex.

At first all the tests should fail since at this point there is no CourseService concrete class.  This is good.  RED, GREEN, REFACTOR.  After running the tests, we can create the class.

01.using System;
02.using System.Collections.Generic;
03.using System.Linq;
04.using System.Text;
05.using GolfTracker.Services.Interfaces;
06.using Microsoft.Practices.Unity;
07.using GolfTracker.DataObjects.Interfaces;
08. 
09.namespace GolfTracker.Services
10.{
11.    public class CourseService : ICourseService
12.    {
13.        [Dependency]
14.        public ICourseRepository CourseRepository { get; set; }
15. 
16.        #region ICRUDService<Course> Members
17. 
18.        public List<GolfTracker.BusinessObjects.Course> GetAll()
19.        {
20.            throw new NotImplementedException();
21.        }
22. 
23.        public GolfTracker.BusinessObjects.Course GetById(Guid id)
24.        {
25.            throw new NotImplementedException();
26.        }
27. 
28.        public Guid Insert(GolfTracker.BusinessObjects.Course model)
29.        {
30.            throw new NotImplementedException();
31.        }
32. 
33.        public Guid Update(GolfTracker.BusinessObjects.Course model)
34.        {
35.            throw new NotImplementedException();
36.        }
37. 
38.        public void Delete(GolfTracker.BusinessObjects.Course model)
39.        {
40.            throw new NotImplementedException();
41.        }
42. 
43.        #endregion
44.    }
45.}

This is the default CourseService class with the Dependency Injection property set and the interface members implemented.

Now I can run tests against this class.  Needless to say the initial tests will fail since all the methods still contain the NotImplementedException() class.  In order to make these tests pass I'll just modify the methods that I need to get working.  For the first test it will be the GetAll() method.

1.public List<GolfTracker.BusinessObjects.Course> GetAll()
2.{
3.    return CourseRepository.GetAll().ToList();
4.}

Now when I run this test it will pass, as long as the number of records in the fake repository hasn't changed.

For the second test I'll need to modify the GetById() method of the CourseService class.

1.public GolfTracker.BusinessObjects.Course GetById(Guid id)
2.{
3.    return CourseRepository.GetById(id);
4.}

At this point when I run all tests, they all turn Green!

Stay tuned and in the next episode I'll move up to the presentation layer and begin setting everything up that I need to make the application work the way I need and also help me generate code using tooling such as T4 templates.

Comments

    No comments yet.

 

User Name:
(Required)
Email:
(Required)