Faking / mocking the interface gives the error "no default constructor", how can this be?

I am trying to write a unit test of a repository implementation. The repository uses RavenDB as a database. For unit tests, I would like to make fun of parts of RavenDB. To create fakes, I use FakeItEasy. I figured there would be no taunting / falsification problems, as the RavenDB API is accessible through interfaces.

I have a problem while trying to instantiate a specific layout. The relevant parts of my unit test code are as follows:

[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 creating an instance of IRavenQueryable, I get an exception. This is the magazine from runner Xunit.net:

 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) 

A “constructor without a default constructor” makes no sense, because what I'm trying to fake is an interface. Does anyone have a suggestion what could be the problem?

+7
source share
4 answers

You are right that the exception message does not make any sense, this is a mistake. It would be great if you could provide a VS solution that reproduces the error and writes the problem here: https://github.com/patrik-hagne/FakeItEasy/

The error is that the wrong exception message is being used, however there must be something wrong, which makes the false creation incorrect. Is the "UserDocument" type public? If it is internal, and you gave it access to the test project using InternalsVisibleToAttribute, you should also give it access to the proxy library: https://github.com/FakeItEasy/FakeItEasy/wiki/How-to-fake-internal - (Friend-in-VB) -types .

+6
source

The IRavenQueryable<T> interface has a restriction where T : new() ?

If so, and UserDocument does not provide the-less ctor option, this can cause problems.

+2
source

I just ran into this, but my problem was not in internal types. My problem was an assembly containing a type that is not in the bin folder of the unit test project.

It seems that FakeItEasy throws this error when it cannot solve the type it needs to fake. (It makes sense why an internal type in another assembly will cause the same error.)

So, I had a Project Foo that the project pane refers to. The project panel had an open interface that referenced the public type from Project Foo. Project Bar.Tests has a link to the project panel, but not Project Foo. When I create Bar.Tests, Bar.dll is placed in the bin folder, but Foo.dll does not. When FakeItEasy tries to fake my interface, it cannot resolve the type that is in Foo.dll.

Adding a link to Project Foo in my Bar.Tests project ensured that Foo.dll did its best and was there for FakeItEasy, and this error disappeared.

So...

In your case, it may be that your RavenDB assembly (which I assume contains a UserDocument ) refers only to your actual project and is not copied to your unit test output.

+2
source

I know this is an old post, but I ran into the same problem. What I discovered was a problem was the inverse of one of the methods declared in the interface that I was trying to fake. This method returned an object of a particular class, and this class did not have a default constructor with which FakeItEasy could work. If someone else gets this error, try checking the objects returned by your interface, and if the corresponding classes have default constructors.

+1
source

All Articles