开发者

TDD Process Outside-In?

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 ActionResu开发者_StackOverflowlt 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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜