Tuesday, January 20, 2009

Create a stub with

A stub can also be created using Mocking frameworks. Semantically speaking, a stub is a simulated object, just like a mock object, that will support our test so that we can test other things. In short, a stub will always make “happy noises” when being called, and can never be used to see if the test passed or not. Calling VerifyAll() will not verify anything against stub objects. Only against mocks. Most Mocking frameworks contain the semantic notion of a stub and RhinoMocks is no exception.

[Test] public void ReturnResultsFromStub() { MockRepository mocks = new MockRepository(); IGetRestuls resultGetter = mocks.Stub<IGetRestuls>(); using(repository.Record()) { //this is still required //to save the value for verification resultGetter.GetSomeNumber("a"); LastCall.Return(1); } //verify int result = resultGetter.GetSomeNumber("a"); //please note here we don't use mocks.VerifyAll(); because stub // will never break tests, but if we use mocks.VerifyAll() //will not break the test anyway. Assert.AreEqual(1, result); }

Strict Mork vs Non-strict mork

A strict Mock Object will only allow calling methods on it that were explicitly set via Expectations. Any call that is made which either differs by the parameter values defined, or by the method name, will usually be handled by throwing an exception while the method is being called. That means the test fails on the first unexpected method call to a strict mock object.

A Non Strict Mock will allow any call to be made to it even if it was not expected. As long as the call does not require a return value, it will, “make happy noises” and only do what’s necessary for everything in the test to work out. If a method which needs to return a value is called and we did not setup a return value as part of setting up that mock object, a RhinoMocks stub object can return the default value for that method’s return type (0 or null usually). Other frameworks may take different approaches and may throw an exception when the method is not configured to return anything.

A non strict Mock can only fail a test if an expected method was not called. You have to call the VerifyAll() method to find out if such a call is missing from the interaction or the test will pass. You can create Non Strict Mocks using RhinoMocks by calling repository.DynamicMock<type>() instead of calling repository.CreateMock<Type>().

An Example of Mock

[Test] Public void Analyze_TooShortFileName_ErrorLoggedToService() { MockRepository mocks = new MockRepository(); IWebService simulatedService = mocks.CreateMock<IWebService>(); //pre-arrange setting using(mocks.Record()) { simulatedService.LogError("file name was too short "); } //play LogAnalyzer log = new LogAnalyzer(simulatedService); string tooShortFileName="abc.ext"; log.Analyze(tooShortFileName); //verify mocks.VerifyAll(); }

The difference between mocks and stubs

Stubs can’t fail tests. Mocks can do (or they’d be called Stubs). Stubs simply replace an object so that we can test the object under test without problems. The easiest way to tell we are dealing with a Stub is to notice that the Stub can never ever fail the test. The asserts the test uses are always against the class under test. When using Mocks, on the other hand, The test will use the Mock object to verify if the test failed or not. Again, when using a Mock, the Mock object is the object that we use to see if the test failed or not.

Mock is normally used in the internal working of a void method, which has no value return.

Unit Test Best practices

  • Arrange test in your solution

    It is common pratice to have a test class per tested class, a test rpoject per tested project and at lest one test method per tested method.

  • Naming tests: [MethodUnderTest]_[Scenario]_[ExpectedBehavior]
  • Use [Setup] and [TearDown] attributes to reuse code in your tests such as creating and initializing common objects all your tests use.
  • Don’t use [Setup] and [TearDown] to initialize or destroy objects which are not shared throughout the test class in all the tests, as it makes the tests less understandable (the reader won’t know which tests use the setup method and which don’t).

Saturday, January 17, 2009

Value object and Persistance

It is confusing to mixed value object with its persistence. We know value has has no identity. How about primary key in database. Every table in database has an primary key. Isn't that key the identity of value object if we want to persist the value object to database? Here we mix the domain model with the persistence.

In domain model, we care about object's behavior, persistence is irrelevant. For example, an order is an entity because we have a use case that get an order by an order id. But order row, it is not an entity because we don't have a use case to get order row without reference to other object. We need to have an order id, to get an order row. Although we can argue that in the order row table, each record still has an primery key( orderId, productId), but that key does not make the order row object an entity. Because it does not make sense to get the an order row without an order. Oder row is parasite of order. Contrary to this, customer is an entity, event Order (an entity object reference customer). Customer does not depend on the existence of an order.

Aggregates are groups of objects that work and live together. We group them along natural operational lines, and one entity serves as the aggregate root. The aggregate root serves as the entry point and the hub of operations for all objects in the aggregate. An aggregate can have many objects, or it can just be a single entity, but the aggregate root is always an entity since the aggregate root must be able to stand on its own, and only entities can stand on their own.

What is the cost of catching an exception

We all known that following an exception without using it is quite silly. How does it really hurt performance. It turns out that difference is very small.

DateTime entry = DateTime.Now; for (int i = 0; i < 100000; i++) { try { throw new Exception("something wrong"); } //catch catch (Exception ex) { } } DateTime exit = DateTime.Now; TimeSpan ts = exit - entry; Console.WriteLine(ts.TotalMilliseconds); //catch 2593.7002 //no catch 2531.2014

Friday, January 9, 2009

The order of route is important in asp.net mvc

I have try to add route to reroute the default.aspx to home handler.

routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = "" } // Parameter defaults ); routes.MapRoute("default.aspx", "default.aspx", new { controller = "Home", action = "Index", id = "" });

It throw an exception "The controller for path '/default.aspx' could not be found or it does not implement IController.". Why, it turns out the order of adding route is important. I should put my routing of "default.aspx" on top of "{controller}/{action}/{id}".