The Inquisitive Coder - Davy Brion’s Blog

Trying to walk that thin line between intelligence and ignorance

Archive for January, 2008

yes that’s right, i AM mocking you!

Posted by Davy Brion on 6th January 2008

Up until now, i’ve always written my stubs and (simple) mocks myself… But now i needed to test the interaction between two classes and i really didn’t feel like writing the mock and the verification logic myself again, so i figured it was time to finally learn how to use a real mocking framework. I picked Ayende’s Rhino Mocks, mainly because i find myself agreeing a lot with the stuff he says… so i figured his mocking framework would be a pretty safe bet.

Anyway, so i needed to test the interaction between two classes. I have the following interface:

    public interface ICheckClassMapping : ICheck

    {

        ICollection<ClassMapping> Select(ICollection<ClassMapping> classMappings);

        void Check(ClassMapping classToCheck, MetaDataStore store);

    }

And then i have a class which has to interact with instances of the ICheckClassMapping interface. This class first needs to call the Select method and pass a collection of ClassMappings to it. Each ClassMapping in the returned collection of ClassMappings must be passed to the Check method. Any ClassMapping which was not returned by Select can not be passed to the Check method. So when i wanted to write a test for this, i really didn’t feel like writing this kind of mock myself. Enter Rhino Mocks… This is the result:

        [Test]

        public void Run_StoreHasThreeClassMappingsAndCheckReturnsTwo_OnlySelectedMappingsAreChecked()

        {

            MappingMetaDataStore mappingStore = new MappingMetaDataStore();

            MetaDataStore store = new MetaDataStore(null, mappingStore);

 

            ClassMapping c1 = TestMappingFactory.CreateClassMapping(MappingSettings.Defaults, “c1″);

            ClassMapping c2 = TestMappingFactory.CreateClassMapping(MappingSettings.Defaults, “c2″);

            ClassMapping c3 = TestMappingFactory.CreateClassMapping(MappingSettings.Defaults, “c3″);

            mappingStore.AddClassMappings(c1, c2, c3);

 

            MockRepository mockRepository = new MockRepository();

            ICheckClassMapping check = mockRepository.CreateMock<ICheckClassMapping>();

            Expect.Call(check.Select(mappingStore.ClassMappings)).Return(new List<ClassMapping>() { c1, c3 });

            Expect.Call(delegate { check.Check(c1, store); });

            Expect.Call(delegate { check.Check(c3, store); });

            mockRepository.ReplayAll();

 

            new CheckClassMappingRunner().Run(check, store, null);

            mockRepository.VerifyAll();

        }

The first couple of lines just set up the MetaDataStore with 3 ClassMappings… And then comes the interesting part:

            MockRepository mockRepository = new MockRepository();

            ICheckClassMapping check = mockRepository.CreateMock<ICheckClassMapping>();

Here we create the MockRepository and create a mock object that implements our ICheckClassMapping interface. This will generate a type at runtime that implements the interface and return an instance of that type to us. Now it’s time to specify what we expect of our mock:

            Expect.Call(check.Select(mappingStore.ClassMappings)).Return(new List<ClassMapping>() { c1, c3 });

            Expect.Call(delegate { check.Check(c1, store); });

            Expect.Call(delegate { check.Check(c3, store); });

The first thing i expect of my mock is that its Select method is called and that it will receive the defined ClassMappings as its parameter. Then we instruct the mock to return a new list of ClassMappings containing only the first and third ClassMapping.
After that, we specify that we expect the mock’s Check method to be called with the first ClassMapping instance as a parameter, together with the store variable. And then we expect the same but with the third ClassMapping instance.

Then we instruct the MockingRepository to switch all known mocks (in this case, just one) to ‘replay’ mode:

            mockRepository.ReplayAll();

This basically means that the mock will replay the expectations we set on it as it’s being used by our code.

After that, we call the method we’re actually testing and then we ask the MockingRepository to verify that our expectations are correct:

            new CheckClassMappingRunner().Run(check, store, null);

            mockRepository.VerifyAll();

This works great… i kinda feel stupid for only learning this now :)

Share/Save/Bookmark

Posted in Software Development, Test Driven Development | No Comments »

Noma Checks Preview

Posted by Davy Brion on 4th January 2008

This is just a small preview of how to implement Noma checks. The classes you’ll see below work, but i still have to write the engine which runs these checks and feeds them the correct data. But i’m pretty happy with how the implementation of checks looks at the moment, so i wanted to post something about it.

First of all, there’s the ICheck interface which looks like this:

    public interface ICheck {}

pretty meaningless huh? I’m just using this as a base interface type to identify all different kinds of Noma checks. For instance, here’s the interface that you’ll need to implement if you want to perform a check on a ClassMapping:

    public interface ICheckClassMappings : ICheck

    {

        ICollection<ClassMapping> Select(ICollection<ClassMapping> classMappings);

        void Check(ClassMapping classToCheck, MetaDataStore store);

    }

The Select method is passed all known ClassMappings, and you’ll need to return the ones that your check is interested in. Each one of the selected ClassMappings will then be passed to the Check method along with the entire MetaDataStore which you’ll use to look up all the data you need to perform your check.

If you want to write a check for something that belongs to a ClassMapping, you’ll need to implement the generic ICheck interface:

    public interface ICheck<T> : ICheck

    {

        ICollection<T> Select(ICollection<T> mappings, ClassMapping parentClassMapping);

        void Check(T mappingToCheck, ClassMapping parentClassmapping, MetaDataStore store);

    }

The type parameter will be the kind of mapping you want to check, like a PropertyMapping for example. The Select method will then receive a collection of all these mappings per ClassMapping, along with a reference to the ClassMapping the mappings belong to. You’ll then need to return a collection of all the mappings you want to perform the check on. Each of these will then be passed to the Check method, along with the reference of the ClassMapping it belongs to, and a reference to the MetaDataStore.

To make it more clear, i’ll show you two examples. First of all, there is the TableExists check:

using System.Collections.Generic;

using System.Linq;

 

using Noma.NHibernate.Mappings;

 

using NUnit.Framework;

 

namespace Noma.Runner.Checks.MappingToDatabase.Class

{

    public class TableExists : ICheckClassMappings

    {

        public ICollection<ClassMapping> Select(ICollection<ClassMapping> classMappings)

        {

            return classMappings.Where(c => !string.IsNullOrEmpty(c.Table)).ToList();

        }

 

        public void Check(ClassMapping classToCheck, MetaDataStore store)

        {

            Assert.IsNotNull(store.GetTable(classToCheck.Schema, classToCheck.Table),

                “Table [{0}].[{1}] was not found”, classToCheck.Schema, classToCheck.Name);

        }

    }

}

Pretty simple right? It selects each ClassMapping that has a Table defined, and then in the Check method we use the familiar NUnit Assert class to verify that the referenced table actually exists in our MetaDataStore.

And this is how the ColumnExists check looks like:

using System.Collections.Generic;

 

using Noma.Database;

using Noma.NHibernate.Mappings;

using Noma.Runner.Checks.MappingToDatabase.Class;

 

using NUnit.Framework;

 

namespace Noma.Runner.Checks.MappingToDatabase.Property

{

    [RequiresMappingToPassCheck(typeof(TableExists))]

    public class ColumnExists : ICheck<PropertyMapping>

    {

        public ICollection<PropertyMapping> Select(ICollection<PropertyMapping> mappings, ClassMapping parentClassMapping)

        {

            // we need to check all property mappings

            return mappings;

        }

 

        public void Check(PropertyMapping mappingToCheck, ClassMapping parentClassmapping, MetaDataStore store)

        {

            string columnName =

                !string.IsNullOrEmpty(mappingToCheck.ColumnName) ? mappingToCheck.ColumnName : mappingToCheck.Name;

 

            Table table = store.GetTable(parentClassmapping.Schema, parentClassmapping.Table);

 

            Assert.IsNotNull(table.GetColumn(columnName),

                            “Class [{0}] refers to column [{1}] in table [{2}].[{3}] but the column was not found”,

                            parentClassmapping.Name, columnName, parentClassmapping.Schema, parentClassmapping.Table);

        }

    }

}

Notice the usage of the [RequiresMappingToPassCheck]. You can use this to declare dependencies between checks… if one of the checks referenced with the [RequiresMappingToPassCheck] attribute already failed for a particular mapping or its parent ClassMapping, the check will not be executed for that specific mapping. In this case, we depend upon a check that only checks ClassMappings. So the ColumnExists check will not be executed for each ClassMapping that already failed the TableExists check.

In the Select method, you can see we simply return all the PropertyMappings we’ve received since we need to check them all. And in the Check method, we look up the table the ClassMapping refers to, and verify that the referenced column is actually there.

I’ve only just come up with this approach… The checks themselves work already, but as i mentioned earlier, i still need to write the engine to execute these checks, feed them the correct data, and resolve the dependencies between the checks. That should be some pretty interesting code :)

Obviously, you will be able to plug in your own checks which can also have dependencies between them.

Share/Save/Bookmark

Posted in Uncategorized | No Comments »

Sending NHibernate entities over the WCF wire

Posted by Davy Brion on 3rd January 2008

Last year, Tim Scott posted this very good article on how to distribute NHiberate entities through WCF services. In it, he mentions this:

We should mention that this application uses NHibernate 1.02. As of this writing, NHibernate has released version 1.2. We tested the application with NHibernate 1.2 before changing to the NetDataContractSerializer, and verified that it exhibits the same problem. We have not verified that the solution described here will work with NHibnerate 1.2, although we expect it will.

I created a small sample that uses his solution with NHibernate 1.2 and my Northwind example and in this post, we’ll walk through the sample. But first, a little bit of background information. By default, WCF services use the DataContractSerializer to serialize/deserialize types. But when you’re using NHibernate, you’re most likely using some of the persistent collection types and proxies. Some people just want to use the same types serverside and clientside. For instance, retrieving a Customer object with his Orders collection through a service, manipulating one of the Order objects clientside, perhaps remove an order from the collection, send the object graph back to the server, attach it to an nhibernate session, persist the whole thing and be done with it. I’m still somewhat undecided as to whether or not this is a good way of doing things but that’s beside the point of this post. Default WCF services do not make this possible but you can make it work rather easily. WCF includes the NetDataContractSerializer which differs from the normal DataContractSerializer in that it includes CLR type information in the serialized data. This makes the above scenario possible. You do lose all interoperability with other platforms, and your clients need the same types you use server side.

First of all, this is the service contract:

    [ServiceContract]

    public interface ICustomerService

    {

        [UseNetDataContractSerializer]

        [OperationContract]

        IList<Customer> GetCustomersWithTheirOrders();

 

        [UseNetDataContractSerializer]

        [OperationContract]

        void PersistCustomer(Customer customer);

    }

The [UseNetDataContractSerializer] is not a standard WCF attribute, but is a part of Tim Scott’s solution. You can find the implementation of the attribute in his post, or in my code which you can download at the bottom of this post. It basically comes down to this: the serialization behavior of operations decorated with this attribute is modified to use the NetDataContractSerializer instead of the default DataContractSerializer.

The implementation of the service contract looks like this:

    public class CustomerService : ICustomerService

    {

        private static readonly ISessionFactory _sessionFactory;

 

        static CustomerService()

        {

            try

            {

                Configuration configuration = new Configuration().AddAssembly(“Northwind.Domain”);

                _sessionFactory = configuration.BuildSessionFactory();

            }

            catch (Exception e)

            {

                Console.Write(e);

                throw;

            }

        }

 

        public IList<Customer> GetCustomersWithTheirOrders()

        {

            using (ISession session = _sessionFactory.OpenSession())

            {

                return session.CreateCriteria(typeof(Customer))

                    .SetFetchMode(“Orders”, FetchMode.Join)

                    .SetResultTransformer(CriteriaUtil.DistinctRootEntity)

                    .List<Customer>();

            }

        }

 

        public void PersistCustomer(Customer customer)

        {

            using (ISession session = _sessionFactory.OpenSession())

            {

                using (ITransaction transaction = session.BeginTransaction())

                {

                    session.SaveOrUpdate(customer);

                    session.Flush();

                    transaction.Commit();

                }

            }

        }

    }

First of all, this is just an example, that’s why the ISessionFactory is created within the service implementation, in a real system i wouldn’t do this. Anyway, the GetCustomersWithTheirOrders method returns a list of all Customers, with their Orders. An Order contains references to an Employee and a Shipper. The Employee and Shipper will not be retrieved from the database, but NHibernate will initialize them with proxy objects to enable lazy-loading. Obviously, the lazy-loading won’t work once you’re outside of the scope of the NHibernate session, but it’s important to note that there will be proxies in our object graph.

At first i had decorated my entity classes with the [DataContract] and [DataMember] attributes but that really messed up the deserialization of the proxies. Now my Entity classes are only decorated with the [Serializable] attribute. NetDataContractSerializer should work in both cases, but i only got it working properly when they were [Serializable].

Right, so now we have the service contract and the implementation, it’s time to host it. My solution contains an example of a console host as well as a service hosted in IIS. For this post, i’ll just go over the console host and console client. You can find the IIS example (which is practically identical anyway) in the downloadable solution.

So, in the console host project, i have the following in my app.config file:

  <system.serviceModel>

    <services>

      <service name=ServiceImplementation.CustomerService behaviorConfiguration=customerServiceBehavior>

        <endpoint contract=ServiceInterface.ICustomerService binding=wsHttpBinding

                  bindingConfiguration=customerServiceBinding />

        <endpoint contract=IMetadataExchange binding=mexHttpBinding address=mex />

        <host>

          <baseAddresses>

            <add baseAddress=http://localhost:8000/CustomerService/>

          </baseAddresses>

        </host>

      </service>

    </services>

 

    <bindings>

      <wsHttpBinding>

        <binding name=customerServiceBinding maxReceivedMessageSize=2147483647 />

      </wsHttpBinding>

    </bindings>

 

    <behaviors>

      <serviceBehaviors>

        <behavior name=customerServiceBehavior >

          <serviceMetadata httpGetEnabled=true httpGetUrl=“”/>

        </behavior>

      </serviceBehaviors>

    </behaviors>

 

  </system.serviceModel>

The service is then started like this:

        private static void Main(string[] args)

        {

            using (ServiceHost host = new ServiceHost(typeof(CustomerService)))

            {

                host.Open();

 

                Console.WriteLine(“press ENTER to quit”);

                Console.ReadLine();

            }

        }

As you can see, nothing special here… it’s pretty much your typical self-hosting WCF example. Except that the maximum message size has been increased since we’ll be sending large object graphs over the wire.

The client configuration looks like this:

  <system.serviceModel>

    <bindings>

      <wsHttpBinding>

        <binding name=customerServiceBinding maxReceivedMessageSize=2147483647 />

      </wsHttpBinding>

    </bindings>

 

    <client>

      <endpoint address=http://localhost:8000/CustomerService binding=wsHttpBinding name=CustomerServiceEndPoint

                bindingConfiguration=customerServiceBinding contract=ServiceInterface.ICustomerService />

    </client>

 

  </system.serviceModel>

And the client uses the service like this:

        private static void Main(string[] args)

        {

            ChannelFactory<ICustomerService> factory = new ChannelFactory<ICustomerService>(“CustomerServiceEndPoint”);

            ICustomerService proxy = factory.CreateChannel();

            IList<Customer> customers = proxy.GetCustomersWithTheirOrders();

        }

I didn’t write a test for this to prove it works, but if you step through it and you explore the returned object graph using the debugger, you’ll see that everything is of the correct type… even the proxies make it through correctly. Manipulating the graph and using the PersistCustomer method also works, but it’s not in this example anymore because i didn’t wanna pollute my database every time i ran it to test it.

I did have problems when i was hosting the service both in the console and through IIS at the same time… some requests would then fail to deserialize the returned graph properly. If you don’t run both hosts at the same time, it works. I have no idea why this caused issues, but after wasting a few hours trying to figure it out, i just gave up. You can reproduce it by running the ServiceConsoleHost, ServiceClient and ServiceWebClient projects in the solution. Sometimes that just works as well, so you may have to try a few times to get it to fail. So if anyone can shed some light on that issue, i’d be most interested in hearing about it :)

You can download the solution here. Note that this is a Visual Studio 2008 solution…

Share/Save/Bookmark

Tags: ,
Posted in NHibernate, WCF | 27 Comments »