Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I mock Objectresult<T> of Entity Framework Using MOQ

I am using Entity Frameowrk 4.0 and I am calling a stored procedure which returns an ObjectResult and I tried to use MOQ and have not been able to mock ObjectResult. Has anybody been able to mock ObjectResult using moq?

TIA Yaz

like image 646
Yazid Avatar asked May 25 '10 18:05

Yazid


2 Answers

I have this problem too; I'm using database-first design, and the EF 4.x DbContext Generator template to generate my DbContext.

I'm modifying the context generator in the following ways:

  1. Instead of DbSet<T> for entity sets, I am returning IDbSet<T>; this allows me to use InMemoryDbSet<T> for unit testing (Google for implementations);
  2. Instead of ObjectResult<T> for stored procedures, I am returning IEnumerable<T>. Inside the virtual method created for the stored procedure, I load the ObjectResult<T> into a List<T> and return that;
  3. Finally, I extract an interface exposing the entity sets and function imports. This means I can then mock the entire DbContext for super-speedy unit tests. You should still write integration tests that test the database functionality for real, of course.
like image 105
David Keaveny Avatar answered Oct 21 '22 15:10

David Keaveny


ObjectResult (according to the MSDN docs) is a sealed class as such you cannot mock it. The way Mocking libraries like Moq work is that when you do something like

Mock<Foo> fooMock = new Mock<Foo>();

It generates (using Reflection.Emit and various other magic tricks) a class that looks a little like this

public class FooMockingProxy : Foo {

    public override void This() {
        // Mocking interceptors to support Verify and Setup
    }

    public override string That() {
        // Mocking interceptors to support Verify and Setup
    }

}

i.e. It takes the class (interface) you want to Mock and subclasses it (or implements it in the case of an interface). This allows it to put in instrumentation that allows it to check if a method has been called, or returns a certain value (this supports the various Setup and Verify methods). The restrictions to this method of mocking are:-

  • Sealed classes (can't be subclassed)
  • Private members (can't be accessed from a subclass)
  • Methods or properties classes that are not virtual (and therefore cannot be overriden).

One technique you can take when approaching sealed classes is to wrap them in some kind of interface that is Mockable. Alternatively you can try and Mock an interface that the sealed class implements that only your code consumes.

like image 2
John Foster Avatar answered Oct 21 '22 16:10

John Foster