0

I'm trying to do some unit tests that include some Linq to Entities queries. I've recently added .AsNoTracking() and possibly .Includes(x => x.table) to the queries and now they start failing.

I've fixed the .AsNoTracking() issue by adding A.CallTo(() => db.table.AsNoTracking()).Returns(db.table) but I can't figure out how to solve the issue I'm having with .Includes()

The current error I'm encountering is the following:

Castle.DynamicProxy.Generators.GeneratorException: Can not create proxy for type System.Data.Entity.Internal.Linq.IInternalQuery`1[[DataClasses.INVOICE.table
because it is not accessible. Make it public, or internal and mark your assembly with...

EDIT / FIXED: I can solve most of my issues with this by mocking away the getter so that FakeItEasy and AutoFac don't need to worry about the queries I wrote. If I want to test a specific query I'm going to opt for using SQLite instead

Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
Dries
  • 995
  • 2
  • 16
  • 45
  • 1
    `.Include()` has nothing to do with AutoFac. It's an EF Core directive that controls eager loading. What are you trying to do anyway? This doesn't look like DI code at all, it looks like an attempt to mock `IQueryable<>` – Panagiotis Kanavos Jun 27 '23 at 11:02
  • Assuming you're really trying to mock/test EF Core, the code is mocking the wrong things. For starters, EF Core is an ORM, not a database driver. It doesn't deal with tables at all, it deals with *classes*. Any `IEnumerable<>` can be converted to an `IQueryable<>` removing the need for this mocking. Mocking DbSet or DbContext isn't meaningful anyway - you're essentially trying to mock the *implementation* of EF Core itself, not even `IQueryable`. – Panagiotis Kanavos Jun 27 '23 at 11:07
  • For low-fidelity mocking you can use [EF Core's in-memory provider or the SQLite provider in in-memory mode](https://learn.microsoft.com/en-us/ef/core/testing/). The in-memory provider uses a list of objects, so it's not a great way to test eager vs lazy loading. [SQLite in in-memory mode](https://learn.microsoft.com/en-us/ef/core/testing/testing-without-the-database#sqlite-in-memory) gives you a proper database though. – Panagiotis Kanavos Jun 27 '23 at 11:10
  • `now they start failing.` what are the *original* queries and how did they fail? `AsNoTracking` works. `Include` works. The application is probably using them in the wrong way – Panagiotis Kanavos Jun 27 '23 at 11:11
  • For example, a query that did not fail was `db.table.Where(x => x....).ToList()` and now I've added some code to it like this: `db.table.Include(x => x.otherTable).Include("otherTable.subTable").Include("otherTable.subTable2").AsNoTracking()`. And now the tests fail. The tables are DBSet's by the way – Dries Jun 27 '23 at 11:20
  • Claiming DbSets are tables doesn't make them so. `Include` doesn't accept table names. It **only** tells EF which *relations* to load eagerly. This has nothing to do with tables and quite often these relations may *not* be using the table you assume . It may not even generate a JOIN. In the typical `Posts` and `Blogs` example, `posts.Include(x=>x.Blogs)` tells EF to eagerly load a Post's blogs but *doesn't* tell it to join with Blogs. If you use split queries, EF will load the posts, then load the blogs that match the Post IDs. In EF Core 7, it will use the `PostBlogs` join table transparently – Panagiotis Kanavos Jun 27 '23 at 11:25
  • Thanks for the information. It doesn't really match with my question though. As I've edited in the original question I've figured something out by abstracting away some more code so it can be faked more easily – Dries Jun 27 '23 at 11:45
  • On the contrary, it says the question is wrong. You aren't mocking or abstracting your database access, you're trying to test your mock code. You'll have to add a lot more mocks as more and more queries fail – Panagiotis Kanavos Jun 27 '23 at 11:51
  • Autofac doesn't mock anything, it's a DI framework, so the questions and tags are wrong. I'm glad you got things working (it appears), but if you actually end up stumped you'll need to overhaul the question quite a bit before anyone can answer. – Travis Illig Jun 28 '23 at 14:00

0 Answers0