TDD with repository pattern

In my new project, I decided to try with TDD. And in very beginning I encountered a problem. First thing that I want to do in my application is to give ability to read data from data source. For this purpose, I want to use repository pattern.
And now:

  • If test are for real implementation of repository interface, I will be testing class that has access to database, and I know that I should avoid that.
  • If test are for not real implementation of repository pattern, I Will be testing well… just mock. There will be no any piece of production code tested in those unit tests.

I’m thinking about this from two days and still cannot come up with any reasonable solution. What I should do?

What a repository does is translate from your domain onto your DAL framework, such as NHibernate or Doctrine, or your SQL-executing classes. This means that your repository will call methods on said framework to perform its duties: your repository constructs the queries needed to fetch the data. If you’re not using an ORM-framework (I hope your are…), the repository would be the place where raw SQL-statements are built.

The most basic of these methods is the save: in most cases this will simply pass the object from the repository onto the unit of work (or the session).

public void Save(Car car)
{
    session.Save(car);
}

But let’s look at another example, for example fetching a car by its ID. It might look like

public function GetCarWithId(String id)
{
    return Session.QueryOver<Car>()
                    .Where(x => x.Id == id)
                    .SingleOrDefault();
}

Still not too complex, but you can imagine with multiple conditions (get me all the cars made after 2010 for all brands in the ‘Volkswagen’ group) this gets tricky. So in true TDD fashion you need to test this. There are several ways to do this.

Option 1: Mock the calls made to the ORM framework

Sure, you can mock the Session-object and simply assert that the right calls are made. While this tests the repository, it is not really test-driven because you are just testing that the repository internally looks the way you want it to. The test basically says ‘the code should look like this’. Still, it is a valid approach but it feels like this kind of test has very little value.

Option 2: (Re)build the database from the tests

Some DAL-frameworks give you the ability to build the complete structure of the database based on the mapping files you create to map the domain onto the tables. For these frameworks the way to test repositories is often to create the database with an in-memory database in the first step of the test and add objects using the DAL-framework to the in-memory database. After this, you can use the repository on the in-memory database to test if the methods work. These tests are slower, but very valid and drive your tests. It does require some cooperation from your DAL-framework.

Option 3: Test on an actual database

Another approach is to test on an actual database and isolate the unittest. You can do this in several ways: surround your tests with a transaction, clean up manually (would not recommend as very hard to maintain), completely rebuild the database after each step… Depending on the application you are building this may or may not be feasible. In my applications I can completely build a local development database from source control and my unittests on repositories use transactions to fully isolate the tests from each other (open transaction, insert data, test repository, rollback transaction). Every build first sets up the local development database and then performs transaction-isolated unittests for the repositories on that local development database. It’s a little slower then a pure Unittest but the tests are extremely valuable and catch a lot of issues.

Don’t test the DAL

If you are using a DAL framework such as NHibernate, avoid the need to test that framework. You could test your mapping files by saving, retrieving and then comparing a domain object to make sure everything is okay (be sure to disable any sort of caching) but it’s not as required as a lot of other tests you should be writing. I tend to do this mostly for collections on parents with conditions on the children.

When testing the return of your repositories you could simply check to see if some identifying property on your domain object matches. This can be an id but in tests it’s often more beneficial to check a human readable property. In the ‘get me all the cars made after 2010….’ this could simply check that five cars are returned and the license plates are ‘insert list here’. Added benefit is that it forces you to think about sorting AND your test automatically forces the sorting. You’d be surprised how many applications either sort multiple times (return sorted from the database, sort before creating a view object and then sort the view object, all on the same property just in case) or implicitly assume the repository sorts and accidentally remove that somehwere along the way, breaking the UI.

‘Unit test’ is just a name

In my opinion, unit tests should mostly not hit the database. You build an application so that every piece of code that needs data from a source does this with a repository, and that repository is injected as a dependency. This allows for easy mocking and all the TDD-goodness you want. But in the end you want to make sure that your repositories perform their duties and if the easiest way to do that is hit a database, well, so be it. I’ve long let go of the notion that ‘unit tests should not touch the database’ and learned that there are very real reasons to do this. But only if you can do this automatically and repeatedly. And weather we call such a test a ‘unit test’ or an ‘integration test’ is moot.

1

  1. Don’t test trivial or obvious repository methods.

    If the methods are trivial CRUD operations, all you’re really testing is whether parameters are mapped correctly. If you have integration tests, such errors will become immediately apparent anyway.

    This is the same principle that applies to trivial properties, like this one:

    public property SomeProperty
    {
        get { return _someProperty; }
        set { _someProperty = value; }
    }
    

    You don’t test it, because there’s nothing to test. There’s no validation or other logic in the property that needs to be verified.

  2. If you still want to test those methods…

    Mocks are the way to do it. Remember, these are Unit Tests. You don’t test the database with unit tests; that’s what Integration Tests are for.

More Information
The Full Stack, Part 3: Building a Repository using TDD (start watching at about 16 minutes in).

7

In Test Driven Development: By Example (Beck, Kent 2002) – Chapter 27. Testing Patterns, Kent explains how you can use mocks to test the Database interface. In short, you can have a mocked version of you database interface object, or ORM if you’re using one, and check if the queries (or ORM method calls) are the expected ones. For example:

function testCustomerLookup() {
   var db = new MockDatabase();
   db.expectQuery("SELECT name FROM customers WHERE id = 123");
   db.returnResult("Customer 1");
   var repo = new UserRepository(db);
   expect(repo.getCustomerById(123)).toEqual("Customer 1");
}

One could argue that you should not test it because you’re more or less testing the implementation and just the argument translation from one layer to another. I am not convinced by this argument, since it is still code and you can mess with it. I think that this theses comes from the fact that it is hard to effectively test the Database interface and people don’t won’t to deal with it. But I think that the vast majority of your code should be tested, and that is no exception.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa

TDD with repository pattern

In my new project, I decided to try with TDD. And in very beginning I encountered a problem. First thing that I want to do in my application is to give ability to read data from data source. For this purpose, I want to use repository pattern.
And now:

  • If test are for real implementation of repository interface, I will be testing class that has access to database, and I know that I should avoid that.
  • If test are for not real implementation of repository pattern, I Will be testing well… just mock. There will be no any piece of production code tested in those unit tests.

I’m thinking about this from two days and still cannot come up with any reasonable solution. What I should do?

What a repository does is translate from your domain onto your DAL framework, such as NHibernate or Doctrine, or your SQL-executing classes. This means that your repository will call methods on said framework to perform its duties: your repository constructs the queries needed to fetch the data. If you’re not using an ORM-framework (I hope your are…), the repository would be the place where raw SQL-statements are built.

The most basic of these methods is the save: in most cases this will simply pass the object from the repository onto the unit of work (or the session).

public void Save(Car car)
{
    session.Save(car);
}

But let’s look at another example, for example fetching a car by its ID. It might look like

public function GetCarWithId(String id)
{
    return Session.QueryOver<Car>()
                    .Where(x => x.Id == id)
                    .SingleOrDefault();
}

Still not too complex, but you can imagine with multiple conditions (get me all the cars made after 2010 for all brands in the ‘Volkswagen’ group) this gets tricky. So in true TDD fashion you need to test this. There are several ways to do this.

Option 1: Mock the calls made to the ORM framework

Sure, you can mock the Session-object and simply assert that the right calls are made. While this tests the repository, it is not really test-driven because you are just testing that the repository internally looks the way you want it to. The test basically says ‘the code should look like this’. Still, it is a valid approach but it feels like this kind of test has very little value.

Option 2: (Re)build the database from the tests

Some DAL-frameworks give you the ability to build the complete structure of the database based on the mapping files you create to map the domain onto the tables. For these frameworks the way to test repositories is often to create the database with an in-memory database in the first step of the test and add objects using the DAL-framework to the in-memory database. After this, you can use the repository on the in-memory database to test if the methods work. These tests are slower, but very valid and drive your tests. It does require some cooperation from your DAL-framework.

Option 3: Test on an actual database

Another approach is to test on an actual database and isolate the unittest. You can do this in several ways: surround your tests with a transaction, clean up manually (would not recommend as very hard to maintain), completely rebuild the database after each step… Depending on the application you are building this may or may not be feasible. In my applications I can completely build a local development database from source control and my unittests on repositories use transactions to fully isolate the tests from each other (open transaction, insert data, test repository, rollback transaction). Every build first sets up the local development database and then performs transaction-isolated unittests for the repositories on that local development database. It’s a little slower then a pure Unittest but the tests are extremely valuable and catch a lot of issues.

Don’t test the DAL

If you are using a DAL framework such as NHibernate, avoid the need to test that framework. You could test your mapping files by saving, retrieving and then comparing a domain object to make sure everything is okay (be sure to disable any sort of caching) but it’s not as required as a lot of other tests you should be writing. I tend to do this mostly for collections on parents with conditions on the children.

When testing the return of your repositories you could simply check to see if some identifying property on your domain object matches. This can be an id but in tests it’s often more beneficial to check a human readable property. In the ‘get me all the cars made after 2010….’ this could simply check that five cars are returned and the license plates are ‘insert list here’. Added benefit is that it forces you to think about sorting AND your test automatically forces the sorting. You’d be surprised how many applications either sort multiple times (return sorted from the database, sort before creating a view object and then sort the view object, all on the same property just in case) or implicitly assume the repository sorts and accidentally remove that somehwere along the way, breaking the UI.

‘Unit test’ is just a name

In my opinion, unit tests should mostly not hit the database. You build an application so that every piece of code that needs data from a source does this with a repository, and that repository is injected as a dependency. This allows for easy mocking and all the TDD-goodness you want. But in the end you want to make sure that your repositories perform their duties and if the easiest way to do that is hit a database, well, so be it. I’ve long let go of the notion that ‘unit tests should not touch the database’ and learned that there are very real reasons to do this. But only if you can do this automatically and repeatedly. And weather we call such a test a ‘unit test’ or an ‘integration test’ is moot.

1

  1. Don’t test trivial or obvious repository methods.

    If the methods are trivial CRUD operations, all you’re really testing is whether parameters are mapped correctly. If you have integration tests, such errors will become immediately apparent anyway.

    This is the same principle that applies to trivial properties, like this one:

    public property SomeProperty
    {
        get { return _someProperty; }
        set { _someProperty = value; }
    }
    

    You don’t test it, because there’s nothing to test. There’s no validation or other logic in the property that needs to be verified.

  2. If you still want to test those methods…

    Mocks are the way to do it. Remember, these are Unit Tests. You don’t test the database with unit tests; that’s what Integration Tests are for.

More Information
The Full Stack, Part 3: Building a Repository using TDD (start watching at about 16 minutes in).

7

In Test Driven Development: By Example (Beck, Kent 2002) – Chapter 27. Testing Patterns, Kent explains how you can use mocks to test the Database interface. In short, you can have a mocked version of you database interface object, or ORM if you’re using one, and check if the queries (or ORM method calls) are the expected ones. For example:

function testCustomerLookup() {
   var db = new MockDatabase();
   db.expectQuery("SELECT name FROM customers WHERE id = 123");
   db.returnResult("Customer 1");
   var repo = new UserRepository(db);
   expect(repo.getCustomerById(123)).toEqual("Customer 1");
}

One could argue that you should not test it because you’re more or less testing the implementation and just the argument translation from one layer to another. I am not convinced by this argument, since it is still code and you can mess with it. I think that this theses comes from the fact that it is hard to effectively test the Database interface and people don’t won’t to deal with it. But I think that the vast majority of your code should be tested, and that is no exception.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật