Friday, October 10, 2014

Chill and the AutoMocking Container

One of the most important ways on how Chill helps with unit testing is by using an auto mocking container.

Compare the following code snippets:

   1: [TestMethod]
   2: public void TestWithoutTheChillFactor()
   3: {
   4:     // You have to explicitly create mocks for your dependencies 
   5:     // and store them in variables.
   6:     var mockCustomerStore = Substitute.For<ICustomerStore>();
   7:  
   8:     // Also, you have to explicitly create a variable for your test data. 
   9:     var expectedCustomer = new Customer()
  10:     {
  11:         Name = "Erwin",
  12:         Address = "At home",
  13:         Id = 123
  14:     };
  15:  
  16:  
  17:     mockCustomerStore.GetCustomer(123).Returns(expectedCustomer);
  18:  
  19:     // Also, you have to explicitly create the subject under test and insert the mocked dependencies. 
  20:     // Need to add or remove a dependency? prepare yourself to modify ALL your test. 
  21:     var sut = new CustomerController(mockCustomerStore);
  22:  
  23:  
  24:     // Call the actual function.. but you also have to create a variable to store your tests. 
  25:     var result = sut.Get(123);
  26:  
  27:     // Multiple asserts per test? 
  28:     Assert.AreSame(expectedCustomer, result.Model);
  29:     mockCustomerStore.Received().GetCustomer(123);
  30: }

There are a lot of things wrong with this example:


  • The knowledge about which dependencies by your Subject are needed are duplicated among all your tests.
  • In each test, you'll have to explicitly create mock objects. This clutters your test with code that does add any value.
  • Multiple asserts per test make it more difficult to figure out what exactly goes wrong.
  • No explicit structure to this test. What exactly is setup code.
  • Even though most tests use a subject, a result and variables, the naming of these variables will be very different across different tests by different authors, making them more difficult to understand.

Compare this with a Chill example:


   1: public class When_retrieving_existing_customer : GivenSubject<CustomerController, View>
   2:     {
   3:         const int customerId = 12;
   4:  
   5:         public When_retrieving_existing_customer()
   6:         {
   7:             Given(() =>
   8:             {
   9:                 // Storage for data used in the test. No need to create fields or variables. 
  10:                 SetThe<Customer>().To(EntityMother.BuildACustomer()
  11:                     .With(x => x.Id = customerId));
  12:  
  13:                 The<ICustomerStore>().GetCustomer(customerId).Returns(The<Customer>());
  14:             });
  15:  
  16:             // Subject under test is created automatically and accessable via the Subject property
  17:             When(() => Subject.Get(customerId));
  18:         }
  19:  
  20:  
  21:  
  22:         [Fact]
  23:         public void Then_view_is_returned()
  24:         {
  25:             Result.Should().NotBeNull();
  26:         }
  27:  
  28:         [Fact]
  29:         public void Then_model_is_the_existing_custmoer()
  30:         {
  31:             Result.Model.Should().Be(The<Customer>());
  32:         }
  33:     }

The automocking container sets up your Subject and automatically injects mock objects for any dependencies it needs. This is great if you have many tests against the same subject and you need to add a dependency. Your tests might fail, but that's exactly what you want. But they still compile and run!

There is no need to explicitly create mock objects anymore. The The<> method will create, register and return a mock object for you, ready for use.

If you want to explicitly register a value, you can use the SetThe<>().To() method to an object. There is also a shorthand for this: UseThe().

Note the use of the .With() extension method. This simple little extension method makes it easy to modify objects afther they have been built, in a very clean way.

1 comment:

  1. học kế toán tại thanh xuân
    khoá học kế toán thuế
    học kế toán tại long biên
    luyện thi toeic
    trung tâm đào tạo kế toán tại nghệ an
    học kế toán tại cầu giấy
    trung tâm kế toán tại cầu giấy
    học kế toán tại bình dương linh hồn Hi Nhã. Rất nhanh, linh hồn Hi nhã lúc này bằng mắt thường cũng
    có thể thấy được tốc độ chữa trị, tăng trưởng lên. Mà trong khi linh hồn
    Hi Nhã đạt đến độ bão hòa, thì linh hồn Thiên sứ nọ cũng bị Đoạn Vân hấp
    thu được không ít rồi.

    Nha, Thiên sứ quả nhiên không hổ danh là sinh vật quỷ dị do linh hồn
    trải qua Chuyển Sình Trì mà sinh ra,thực sự là đại bổ. Trải qua một phen
    hấp thu, chân khí trong cơ thể Đoạn Vân đề cao lên không ít, đặc biệt là
    tinh thần, thực sự tăng cường lên không biết bao nhiêu!

    Linh hồn Hi Nhã hẳn là cũng coi như được chữa trị tốt rồi! Nhưng bây giờ
    một vấn đề mới lại phát sinh. Linh hồn Hi Nhã căn bản không có tỉnh lại.
    Từ linh hồn Thiên sứ có thể sinh ra sợ hãi, phát ra than khóc, Đoạn Vân
    liền dám khẳng định linh hồn cũng có thể có suy nghĩ riêng của mình,
    thậm chí rất có thể suy nghĩ của một người căn bản là do linh hồn khống chế.

    Tuy nhiên đã bất tỉnh thì cứ bất tỉnh đi, lão tử vẫn phải làm đau ngươi
    khi ngươi đang ngủ. Sau khi dùng tinh thần lực rất mạnh đưa linh hồn Hi
    Nhã đặt lên người nàng, Đoạn Vân bắt đầu một đợt cứu trị khác.

    Lần này chủ yếu là khôi phục công năng của các cơ quan nội tạng. Còn như
    thế nào làm cho linh hồn Hi Nhã tỉnh lại, Đoạn Vân muốn thông qua kích
    thích hệ thần kinh thử lại một lần.

    tiếng anh cho người mới bắt đầu
    trung tâm kế toán tại đà nẵng
    học kế toán ở đồng nai

    http://kylin1st.com
    http://cattleyavn.com
    http://kenyseo.com

    ReplyDelete