Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Faking/mocking an interface gives "no default constructor" error, how can that be?

I'm trying to write a unit test of a repository implementation. The repository uses RavenDB as a database. For the unit tests, I would like to mock the RavenDB parts. In order to create the mocks (fakes) I'm using FakeItEasy. I figured there wouldn't be any problems with the mocking/faking since the RavenDB API is accessed through interfaces.

I do however have a problem when trying to instantiate a specific mock. The relevant parts of my unit test code looks like this:

[Fact]
public void Test() {
    UserDocument doc = ...;
    IQueryable<UserDocument> where = A.Fake<IQueryable<UserDocument>>();
    A.CallTo(() => where.First()).Returns(doc);
    IRavenQueryable<UserDocument> query = A.Fake<IRavenQueryable<UserDocument>>();
    IDocumentSession session = A.Fake<IDocumentSession>();
    A.CallTo(() => session.Query<UserDocument>()).Returns(query);
    IDocumentStore store = A.Fake<IDocumentStore>();
    A.CallTo(() => store.OpenSession()).Returns(session);
    .
    .
    .
}

When instantiating the IRavenQueryable fake I get an exception. This is the log from the Xunit.net runner:

UnitTest.Test : FakeItEasy.Core.FakeCreationException : 
  Failed to create fake of type "System.Linq.IQueryable`1[UserDocument]".

  Below is a list of reasons for failure per attempted constructor:
    No constructor arguments failed:
      No default constructor was found on the type System.Linq.IQueryable`1[UserDocument].


Stack Trace:
   vid FakeItEasy.Core.DefaultExceptionThrower.ThrowFailedToGenerateProxyWithResolvedConstructors(Type typeOfFake, String reasonForFailureOfUnspecifiedConstructor, IEnumerable`1 resolvedConstructors)
   vid FakeItEasy.Creation.FakeObjectCreator.TryCreateFakeWithDummyArgumentsForConstructor(Type typeOfFake, FakeOptions fakeOptions, IDummyValueCreationSession session, String failReasonForDefaultConstructor, Boolean throwOnFailure)
   vid FakeItEasy.Creation.FakeObjectCreator.CreateFake(Type typeOfFake, FakeOptions fakeOptions, IDummyValueCreationSession session, Boolean throwOnFailure)
   vid FakeItEasy.Creation.DefaultFakeAndDummyManager.CreateFake(Type typeOfFake, FakeOptions options)
   vid FakeItEasy.Creation.DefaultFakeCreatorFacade.CreateFake[T](Action`1 options)

The "no default constructor found" doesn't make any sense since what I'm trying to fake is an interface. Does anyone have a suggestion what the problem might be?

like image 466
David Nordvall Avatar asked Sep 26 '11 18:09

David Nordvall


1 Answers

I know it is an old post, but I ran into the same issue. What I found to be the problem was a return type of one of the methods declared into the interface I was trying to fake. This method was returning an object of a certain class, and this class didn't have a default constructor with which FakeItEasy could work. If someone else gets this error try to check the objects your interface is returning, and if the corresponding classes have the default constructors.

like image 198
IonutC Avatar answered Oct 12 '22 22:10

IonutC