Living in the Tech Avalanche Generation

A practitioner’s introspective on technology

Archive for April, 2009

Entity Framework Repository Testing

Mark recently asked about testing the Repository / Fetching Strategy / Specification framework that I posted a while back. We can in fact bypass integration testing and by doing some state based testing on the Repository and utilise Specifications to filter the results.

[Test()]
public void mock_customers_only_where_in_germany()
{
    NorthwindEntities fake_entity_model = null;
    var mock_repo =
        new Mock<EntitiesRepository<Customer, NorthwindEntities>>
            (fake_entity_model);

    var germany_cust_spec =
        new Specification<Customer>(c => c.Country == “Germany”);

    var orders = new EntityCollection<Order>();
    orders.Add(new Order{Freight = 10M});
    orders.Add(new Order{Freight = 23M});

    mock_repo.Expect
        (repo => repo.AllToIList<ICustomerMakePrefered>())
        .Returns(new List<Customer>()
        {
            new Customer()
            {
                CustomerID = “ALFKI”,
                Country = “Germany”,
                Orders = orders
            },
            new Customer()
            {
                CustomerID = “SIMSE”, Country = “Australia”
            }
        });

    var results = mock_repo.Object.AllToIList<ICustomerMakePrefered>();

    var cust = results.Where(germany_cust_spec.EvalFunc).First();

    cust.Makeprefered();

    Assert.That(cust.Orders.Sum(o => o.Freight) == 0);
    Assert.AreEqual(results.Count, 2);
    Assert.AreEqual(results.First().Country, “Germany”);
    Assert.AreEqual(mock_repo.Object
        .AllToIList<ICustomerMakePrefered>().Count, 2);
}

Where the Customer Entities MakePrefered method looks like this:

public void Makeprefered()
{
    foreach (var order in this.Orders)
    {
        order.Freight = 0M;
    }
}

So with the help of a bit of mocking we mimic the behaviour of the database, test our business logic and all with some degree of speed improvement.

Share/Save/Bookmark

4 comments

GOF Series: Episode #5 : [The Prototype Pattern] - In IronRuby

Firstly let me mention that whilst this series started out as demonstrating the Gang of Fours patterns in C# I have since decided to change direction a little bit and have the rest of the series presented in IronRuby. Why? My Reasons are twofold, firstly there are probably more than enough examples of the patterns in C# that another one will certainly not be missed and second completing the series in IronRuby will serve as great learning tool on the way to better knowing the language. I have previously posted on the Builder Pattern implemented in IronRuby and for that example I used Sapphire in Steel to develop the code and I am really hoping that we get a great code editor for IronRuby when it makes it’s official debut.

What purpose does this pattern serve?

Implementing the prototype pattern facilitates creating a prototypical object and subsequently being able to produce copies of that prototype.

Example Code:

First lets start with our Vehicle manager which will hold the prototyped vehicles that we wish to take copies of.

class VehicleManager
    def initialize
        @cars = {}
    end
    def add key, prototype
        @cars[key] = prototype
    end
    def remove key
        @cars.delete key
    end
    def get_vehicle_by_key key
        @cars[key].deep_copy
    end
end

Next we create a module that we will use as a mixin to extend a ‘vehicles’ behaviour to include cloning.

module Cloneable
    attr_accessor :id
    attr_accessor :horse_power
    def deep_copy
        Marshal.load(Marshal.dump(self))
    end
end
Now some some Cloneable vehicles that our Vehicle manager can work with.
class Car
    include Cloneable
    def initialize horse_power, id
        @id = id
        @horse_power = horse_power
    end
end

class MotorCycle
    include Cloneable
    def initialize horse_power, id
        @id = id
        @horse_power = horse_power
    end
end

All that’s left is to look at how to create some prototype’s using these classes.

$counter = 1

#new up a VehicleManager to store vehicles
#that we are interested in cloning
vmanager = VehicleManager.new

#add a car and motor cycle to the manager
vmanager.add :eighty, Car.new(80, $counter)
$counter += 1
vmanager.add :ninety , MotorCycle.new(90, $counter)

#retrieve clones of the car and motor cycle
vehicle_car = vmanager.get_vehicle_by_key :eighty
vehicle_bike = vmanager.get_vehicle_by_key :ninety

#print the results
puts “The horse power for the car is “ +
     “#{vehicle_car.horse_power} and the ID is :#{vehicle_car.id}”
puts “The horse power for the motor cycle is “ +
     “#{vehicle_bike.horse_power} and the ID is :#{vehicle_bike.id}”
console_ir_prototype_pattern
Yet again the brevity of IronRuby (Ruby) comes to the fore and true to the languages nature, interesting things can be done with less code when you compare to our statically typed friends. I am definately gaining a real appreciation for “composition over inheritance” and as the static languages are now crossing the paradigm divides with features clearly borrowed from both the functional and dynamic worlds, should we be expecting to get the ability to compose our objects in C# or VB.NET sometime in the future?

Share/Save/Bookmark

No comments

Entity Framework Profiler with IronRuby and IronPython Scripting

ir_console_ef_profilerBecause I would like to write my Repositories and monitor their behaviour in the Profiler I decided that I could kill two birds with one console (so to speak). The first bird to kill involved my spending as much time as possible in the pursuit of both learning IronRuby and gaining better understanding of the more interesting problems that can be solved with dynamic languages implemented on top of the DLR. I can see the possibilities of hosting the DLR to provide scripting support to applications and after having implemented my own hosted IronRuby consoles I eventually decided to reuse one that was more fully featured, saving me quite a bit of time by best fitting the Profiler’s needs. The console I chose in the end was IronEditor which is available on codeplex. IronEditor is implemented as a Windows Forms application and so I did have to refactor it a little to make it work as User Control and have the UI behave correctly for asynchronous updates to the UI. Hosting the Windows User Control in the WPF Profiler was of course simple enough by leveraging the WindowsFormsHost.

I had already posted about what to expect from the next iteration of the Profiler and I won’t repeat it here, so if your new to the tool I suggest you look here. One further change I flagged was to remove WCF from the application and have the messaging occur via sockets. I decided against that change and chose instead (see below) to take the opportunity to demonstrate how to use WCF UnTyped Messages with a bit of IoC to achieve a more loosely coupled approach to handling messages. This approach requires writing specific handlers for specific messages that are not in any way coupled to the signature of any RPC / CRUD looking ServiceContract or the shape of any DataContract, and it is a style somewhat (largely) borrowed from NServiceBus. Here’s the code from the WCF Service and I will have more to say on that a bit later with a more detailed post.

Messaging

public void SendAny(Message message)
{
    object msg_in_body = null;

    var container =
        new Castle.Windsor.WindsorContainer();

    //get all the potential handlers in the assembly
    //NOTE: could load all these up at startup and call
    //to find one that matches from memory rather than
    //in the same iteration that adds the components
    //to the container.
    var libTypes = from a in Assembly.GetExecutingAssembly().GetTypes()
                   from i in a.GetInterfaces()
                   from ii in i.GetInterfaces()
                   from g in i.GetGenericArguments()
                   from gi in g.GetInterfaces()
                   where ii.IsAssignableFrom(typeof(IMessageHandler))
                   where gi.IsAssignableFrom(typeof(IMessage))
                   select new
                   {
                       TheType = a,
                       TheIface = i,
                       TheGeneric = g,
                       TheGenericIface = gi
                   };

    //iterate all the handlers
    foreach (var gen in libTypes)
    {
        container.AddComponent(gen.TheType.Name, gen.TheType);
        //attempt to deserialize using the current
        //handlers generic argument (the message)
        msg_in_body =
            MessageSerializer.DeserializeMessage
            (message, gen.TheGeneric);
        if (msg_in_body != null)
        {
            //resolve the message handler in the container
            var the_handler =
                container.Resolve(gen.TheType);
            var handle_method =
                the_handler.GetType().GetMethod(“Handle”);
            if(handle_method != null)
                handle_method.Invoke(the_handler,
                    new[] { msg_in_body });
        }
    }
}

The Messages And Message Handlers

public interface IMessage
{
    Guid MessageID { get; }
}

public interface IMessageHandler {  }

public interface IMessageHandler<TMessage> :
                 IMessageHandler where TMessage : IMessage
{
    void Handle(TMessage message);
}

public class EntityInterceptMessage : IMessage
{
    [XmlElement(Order = 1)]
    public Guid MessageID
    {
        get { return _id; }
        set { _id = value; }
    }

    [XmlElement(Order = 2)]
    public string SqlQueryText
    {
        get { return _sql; }
        set { _sql = value; }
    }

    [XmlElement(Order = 3)]
    public string ProcessID
    {
        get { return _processId; }
        set { _processId = value; }
    }

    //….message members etc

}

public class EntityInterceptMessageHandler :
             IMessageHandler<EntityInterceptMessage>
{
    public void Handle(EntityInterceptMessage message)
    {
        ProfilerModel.EntityMessages.Add(message);
        Console.WriteLine(message.EntityModelName);
    }
}

Running the Application

You can run this code and test it using a supplied IronRuby script named “run_profiler_script.rb”, just make sure you have the Northwind database installed , that the script gets the required changes to match your database details and that the the test projects DLL is ‘required’ from the appropriate location on your hard drive.

require ‘D:/simon.segal/Local Working/Org.TechA.EF.Profiler’ +
    ‘/Org.TechA.EF.Profiler.Tests/bin/Debug’ +
    ‘/Org.TechA.EF.Profiler.Tests.dll’

By downloading you will be accepting the code project open license for the SQL CodeBox control and the Apache License 2.0 for IronEditor, both of which have been integrated into this solution. You can download the Profiler from here.

UPDATE: (Sunday April 19th)

Apologies for having an earlier link to the code being incomplete. The problem has now been rectified.

Share/Save/Bookmark

5 comments

Next Page »

Creative Commons Attribution-ShareAlike 2.5 Australia
Creative Commons Attribution-ShareAlike 2.5 Australia