Monday, June 29, 2009

What is a fake

A fake is a generic term that can be used to describe either a stub or a mock object (handwritten or otherwise), because they both look like the real object. Whether a fake is a stub or a mock depends how it's used in the current test. If it's used to check an interaction(asserted against), it's a mock object. Otherwise, it is a stub.

What is mock

A mock object is a fake object in the system that decides whether the unit test has passed or failed. It does so by verifying whether the object under test interacted as expected with the fake object.

Refactory to break dependency

  • Extract an interface to allow replacing underlying implementation
  • Inject stub implementation into a class under test
  • Receiving an interface at the constructor level.

    If your code under test requires more than one stub to work correctly without dependencies, adding more and more constructors ( or more and more constructor parameters) becomes a hassle, and it can even make the code less readable and less maintainable. One possible solution is using inversion of control containers. You can think of IoC containers as "smart factories" for you objects. A container provide special factory methods that take in the type of object you'd like to create and any dependencies that it needs, and then initialize the object using special configurable rules such as what constructor to call, what properties to set in what order, and so on. They are powerful when put to use on a complicated composite object hierarchy where creating an object requires creating and initializing object serveral levles down the line. Using constructor arguments to initialize objects can make you testing code more cumbersome unless you're using helper frameworks such as IoC containers for object creation. Every tie you add another dependency to the class under test, you have to create a new constructor that takes all other arguments plus a new one, make sure it calls the other constructors correctly, and make sure other users of this class initialize with the new constructor.

    On the other hand, using parameters in constructors is a great way to signify to the user of your API that these parameters are non-optional. They have to be sent in when creating the object.

    If you want these dependencies to be optional, use properties, which is much more relexed way to define optional dependencies adding different constructors to the class for each dependency. If you choose to use constructor injection, you'll probably also want to use IoC containers. This would be a great solution if all code in the world were using IoC, containers. The future of unit testing will use more and more of these Ioc pattern.

  • Receive an interface as a property get or set.

    Use this technique when you want to signify that a dependency of the class under test is optional, or if the dependency has a default instance created that doesn't create any problems during the test.

  • Get a stub just before a method call

Thursday, June 25, 2009

Cancel Hanlder

The cancel handler view provides a way to define activity cancellation logic. A cancel handler has some similarities to the fault handlers just discussed. Like fault handlers, they are attached only to a composite activity.However, cancel handlers don’t catch and handle exceptions. Instead, they specify the cleanup actions that take place when an executing activity is canceled.

actions that take place when an executing activity is canceled. The need for cancel handlers is best illustrated with an example: A ListenActivity is a composite activity that allows you to define multiple child activities under it. Assume that each child of the ListenActivity is a HandleExternalEventActivity that listens for a different external event. With this scenario, each HandleExternalEventActivity is executing at the same time waiting for an event. Only one of these children will eventually receive its event and complete execution. The other sibling activities will be canceled by the ListenActivity parent. By entering a cancel handler for the parent ListenActivity, you define the steps to execute when the incomplete children are canceled. You won’t always need a cancel handler. But if your activities require any cleanup when they are canceled, a cancel handler is an appropriate place to define that logic.

Tuesday, June 23, 2009

ActivityExecutionContext

  1. It is a container of services that is availabe to activities ruing their execution. This set of service is the same for all activities in all WF program instances. Some services are provided by the WF runtime and are always obtainable from AEC. Custom services can be offered by the application that hosts the WF runtime; such services are made available to activities by using the AddService method of WorkflowRuntime. class ReadLine:Activity { private string text; public string Text { get { return text; } } protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext) { WorkflowQueuingService qService = executionContext.GetService<WorkflowQueuingService>(); WorkflowQueue queue = qService.CreateWorkflowQueue(this.Name, true); queue.QueueItemAvailable += ContinueAt; return ActivityExecutionStatus.Executing; } void ContinueAt(object sender, QueueEventArgs e) { ActivityExecutionContext context = sender as ActivityExecutionContext; WorkflowQueuingService qService = context.GetService<WorkflowQueuingService>(); WorkflowQueue queue = qService.GetWorkflowQueue(this.Name); text = (string)queue.Dequeue(); qService.DeleteWorkflowQueue(this.Name); context.CloseActivity(); } }
  2. ActivityExecutionContext is as an API surface through which activities can interact with the (internal) scheduler component of the WF runtime. For example, the ExecuteActivity method requests that a work queue. The CloseActivity method requests that the WF runtime finalize the current activity's transition to the Closed state, and resume the internal bookmark that notifies the parent composite activity of the activity's completion. AEC therefore abstracts the internal machinery of the WF runtime; even though we have explained the execution model of the WF runtime in terms of a scheduler and a work queue, these entities are not represented directly in the public API of the WF programming model. public class Sequence : CompositeActivity { protected override ActivityExecutionStatus Execute(ActivityExecutionContext context) { if (this.EnabledActivities.Count == 0) return ActivityExecutionStatus.Closed; Activity child = this.EnabledActivities[0]; child.Closed += this.ContinueAt; context.ExecuteActivity(child); return ActivityExecutionStatus.Executing; } void ContinueAt(object sender, ActivityExecutionStatusChangedEventArgs e) { ActivityExecutionContext context = sender as ActivityExecutionContext; e.Activity.Closed -= this.ContinueAt; int index = this.EnabledActivities.IndexOf(e.Activity); if ((index + 1) == this.EnabledActivities.Count) { context.CloseActivity(); } else { Activity child = this.EnabledActivities[index + 1]; child.Closed += this.ContinueAt; context.ExecuteActivity(child); } } }
  3. The execution of a WF program instance is episodic, and at the end of each episode when the WF program instance becomes idle, the instance can be persisted in durable storage as continuation. This continuation, because it represents the entirety of the program instance's state that is necessary for resuming its execution, holds the relevant (internal) WF runtime execution state plus user-defined state, sometimes called the application state. The application state is nothing but the WF program instance's tree of activities (the actual CLR objects), which are usually stateful entities. The runtime state includes the state of the scheduler work queue, WF program queues, and bookkeeping information about internally managed bookmarks (such as subscriptions to the Activity.Closed event).

    The resumption point of a bookmark is called an execution handler, so we can refer to the (heap-allocated) execution state required by an execution handler as its execution context. Because an execution handler is typically a method on an activity, we will often refer to this execution context as activity execution context.

    ActivityExecutionContext is a programmatic abstraction for precisely this execution context. ActivityExecutionContext is passed to every execution handler either as an explicit argument (as for Activity.Execute) or as the sender parameter in the case of execution handlers that conform to a standard .NET Framework event handler delegate type.

Test asp.net mvc route

//arrange RouteCollection routes = new RouteCollection(); MvcApplication.RegisterRoutes(routes); var httpContextMock = new Mock<HttpContextBase>(); httpContextMock.Expect(c => c.Request.AppRelativeCurrentExecutionFilePath).Return("~/product/list"); //act RouteData routeData = routes.GetRouteData(httpContextMock.Object); //assert Assert.IsNotNull(routeData, "Should have found the route"); Assert.AreEqual("product", routeData.Value["Controller"]); Assert.AreEqual("list", routeData.Value["action"]); Assert.AreEqual("", routeData.Values["id"]);

Thursday, June 11, 2009

mvc routing

Routing is actually not part of the asp.net mvc component. But mvc depends on this asp.net components. To add a route to the route table, you can use the following code.

Route r = new Route("url", new SomeRouteHandler()); r.Constraints.Add("key", "value"); r.Defaults.Add("key", "value"); r.DataTokens.Add("key", "value"); RouteTable.Routes.Add("route_name", r); // or you can write the code in .net 3.0 syntax, they do the same job //but it looks cleaner. RouteTable.Routes.Add(new Route("url", new SomeRouteHandler()) { Constraints = new RouteValueDictionary(new { key = value }), Defaults = new RouteValueDictionary(new { key = value }), DataTokens = new RouteValueDictionary(new { key = value }), });

asp.net mvc, add some extension method to the RouteCollection like the following.

public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces) { if (routes == null) { throw new ArgumentNullException("routes"); } if (url == null) { throw new ArgumentNullException("url"); } Route route = new Route(url, new MvcRouteHandler()) { Defaults = new RouteValueDictionary(defaults), Constraints = new RouteValueDictionary(constraints) }; if ((namespaces != null) && (namespaces.Length > 0)) { route.DataTokens = new RouteValueDictionary(); route.DataTokens["Namespaces"] = namespaces; } routes.Add(name, route); return route; }

This method create a route use MvcRouteHandler as IRouteHandler. So if use this method, the MVC component comes into play. So you can these extension method to simplify the mvc routing

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

The default values only work when every URL parameters after the one with default also has a default value assigned. So the following code doesn't work.

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

The following code demo a catch-all parameter

routes.MapRoute("r2", "catch/{*all}", new { controller = "test", action = "catch", all="empty" }); public string Catch(string all) { return string.Format("<h1>all:{0}</h1>", all); }

Wednesday, June 10, 2009

EF JOIN

Zlatko Michailov, the Entity SQL program manager at Microsoft, writes in his blog: "A well defined query against a well defined entity data model does not need JOIN. Navigation properties in combination with nesting sub-queries should be used instead. These latter constructs represent task requirements much more closely than JOIN does."—http://blogs.msdn.com/esql/ (November 1, 2007). To show it means, here is an example.

In this model the Contact is referenced by multiple Address. Here we explicitly expression their relationship by a reference object. Because we have this navigation properties, we can write the following code using this navigation properties and sub-query like below.

var test = from c in context.Contacts select new { c.FirstName, c.LastName, StreetsCities = from a in c.Addresses select new { a.Street1, a.City } };

If the navigation properties is missing(as shown in the following chart), then you have to use join.

var test = from c in context.Contacts join address in context.Addresses on c.ContactID equals address.ContactID select new { c.FirstName, c.LastName, StreetsCities = new { address.Street1, address.City } };

Monday, June 8, 2009

Entity Framework stack

The Entity Framework's most prominent feature set and that which you are likely to work with most often is referred to as Object Services. Object Services sits on top of the Entity Framework stack, and provides all the functionality needed to work with objects that are based on your entities. Object Services provides a class called EntityObject and can manage any class that inherits from EntityObject. This includes materializing objects from the results of queries against the EDM, keeping track of changes to those objects, managing relationships between objects, and saving changes back to the database.

EntityClient is the other major API in the Entity Framework. It provides the functionality necessary for working with the store queries and commands (in conjunction with the database provider) connecting to the database, executing the commands, retrieving the results from the store, and reshaping the results to match the EDM.

You can work with EntityClient directly or work with Object Services, which sits on top of EntityClient. EntityClient is only able to perform queries, and it does this on behalf of Object Services. The difference is that when you work directly with EntityClient, you will get tabular results (though the results can be shaped). If you are working with Object Services, it will transform the tabular data created by EntityClient into objects.

The tabular data returned by EntityClient is read-only. Only Object Services provides change tracking and the ability to save changes back to the data store.

Object Services' core object is ObjectContext and ObjectQuery. ObjectContext is like a strongly type entity storage. ObjectQuery is used to retrieve the Entity from ObjectContext. ObjectQuery implements the linq feature, it implments interface, IQueryable, and IEnumberable.

using (AdventureWorksEntities advWorksContext = new AdventureWorksEntities()) { try { // Define an ObjectQuery to use with the LINQ query. ObjectQuery<Product> products = advWorksContext.Product; // Define a LINQ query that returns a selected product. var result = from product in products where product.ProductID == 900 select product; // Cast the inferred type var to an ObjectQuery // and then write the store commands for the query. Console.WriteLine(((ObjectQuery<Product>)result).ToTraceString()); } catch (EntitySqlException ex) { Console.WriteLine(ex.ToString()); } }

The ObjectQuery is the core of Linq to Entity Framework, it will convert the query into Entity SQL, and send it the EntityClient. You can also ask ObjectContext create a ObjectQuery by write write Entity Sql, but eventually the Entity Sql will be executed by the EntityClient. EntityClient will convert the Entity Sql to native sql for the data provider below. Here is some sample code.

var qStr = @"SELECT VALUE c FROM PEF.Contacts AS c WHERE c.FirstName='Robert'"; var contacts = context.CreateQuery<Contact>(qStr);