Unit Testing ObjectResult

I came across an interesting scenario where I wanted to unit test an imported function in the Entity Framework. The initial problem is that an imported function generates code like this:

1
2
3
4
5
public virtual ObjectResult<MyObject> GetData()
        {
   
            return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<MyObject>("GetData");
        }

The key method here is the results are returned as the ObjectResult object which 1) cannot be mocked (using RhinoMocks) because it’s sealed. There are no constructors available to create concrete instances of the object. So the best solution I can come up with is to create a new interface and create two classes that implement the interface, one for the real application and one for unit testing. From here, the unit testing class which has the interface can return anything it likes i.e. fake objects while the other class can call the function import method and return the results.

Firstly, I create the interface

1
2
3
4
5
6
public partial interface IExtendedEntities
    {
       
        IEnumerable<MyObject> GetDataWrapper();

    }

Secondly, I create the class that will use this interface for the real application.

1
2
3
4
5
6
7
public partial class MyClassReal : DbContext, IExtendedEntities
    {
        public IEnumerable<MyObject> GetDataWrapper()
        {
            return this.GetData().AsEnumerable();
        }
    }

Thirdly, create the class that uses the interface for unit testing

1
2
3
4
5
6
7
public partial class MyClassFake : DbContext, IExtendedEntities
    {
        public IEnumerable<MyObject> GetDataWrapper()
        {
            return Builder<MyObject>.CreateListOfSize(10).Build();
        }
    }

When I’m implementing the logic, I can inject (using nInject) an object of the interface IExtendedEntities and call GetDataWrapper();

When unit testing, I can create a new MyClassFake object and return a list of test data. This gives me the control to create a test case of specific test data to be put through the method that gets called to return a set of results from the Imported Function.

Tracking and Not Tracking Objects returned from SqlQuery in Entity Framework

If you don’t want objects to be tracked by the context, you can do this:

1
2
3
4
public ObjectResult<MyObject> GetData()
{
         return this.Database.SqlQuery<MyObject>("call GetData(@p0,@p1,@p2,@p3)", 1, 2, 3, 4);
}

If you want to track objects by the context, you can do this:

1
2
3
4
public ObjectResult<MyObject> GetData()
{
     return ((DbSet<MyObject>)this.MyObjects).SqlQuery("call GetData (@p0,@p1,@p2,@p3)", 1, 2, 3, 4);
}

The different is when you call SqlQuery from the objects DbSet, this will automatically track objects with the current database context.

Referenced Projects in a solution disappear on compile time Visual Studio 2010

Take the following example of a solution:

  • MyProject
  • MyProject.Core
  • MyProject.Infrasturcture

I decide to add a new console application called MyProject.Console. I reference the MyProject.Core into this console application. Everything is working fine until I try to build and run the console application. I get a error saying “Could not find the referenced Assembly.”.

I figured out that when I created the new console application in Visual Studio 2010 it defaulted to .NET 4 Client Profile as the framework and not .NET 4. This is because all my other projects were using the .NET 4 framework.

References

http://stackoverflow.com/questions/4286599/referenced-project-gets-lost-at-compile-time

The property could not be set to a ‘Int16′ value. You must set this property to a non-null value of type ‘Int32′.

I came across the following error when trying to map a stored procedure to a complex type in EF 4+.

The property could not be set to a ‘Int16′ value. You must set this property to a non-null value of type ‘Int32′.

The problem was the Entity Framework was thinking the return data type was Int16 but in fact the complex type value was specified as Int32.

The solution was to make sure that your results from the stored procedure are explicitly set and cast to the right data types. You can do this by using the convert function in T-SQL. Example below.

1
 select convert(int,myValue) from foo

Once you do implement this function into your stored procedures, you can update your mappings in EF and the problem will be fixed (well for me anyway).

Giving Enum’s descriptions

Enums are very good for giving descriptions to values especially numeric values. By default though a enum value name cannot have spaces. Look at the following which shows an example of no spaces between the first enum value name.

1
2
3
4
enum myEnum
{
   Icannothaveaspace = 1
}

A good way to solve this problem is to use the Description attribute from the System.ComponentModel namespace. We can use this attribute to give each enum value a descriptive meaning.

1
2
3
4
5
6
7
8
9
using System.ComponentModel;

 public enum MyEnum
    {
        [Description("Authorised Contact")]
        AuthorisedContact = 1,
        [Description("Assigned Contact")]
        CoauthorisedContact = 2
    }

From here we can create a extension method that uses reflection to get the description attribute for the selected enum value.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static class Extensions
    {
        /// <summary>
        /// Get the description of a enum value using the description attribute
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string GetEnumDescription(this Enum value)
        {
            FieldInfo fi = value.GetType().GetField(value.ToString());

            DescriptionAttribute[] attributes =
                (DescriptionAttribute[])fi.GetCustomAttributes(
                typeof(DescriptionAttribute),
                false);

            if (attributes != null && attributes.Length > 0)
                return attributes[0].Description;
           
            return value.ToString();
        }
    }

To use this, just call GetEnumDescription to get the description of a enum value.

1
2
3
4
5
6
7
8
9
  using Extensions; //Make sure that you use this to get the extension method
 
  public myClass
  {
      public void foo()
      {
          var myDescription = MyEnumValue.GetEnumDescription();
      }
  }