How do I make DbContext in using statement work with unit tests?

dbcontext entity-framework entity-framework-6 unit-testing using

Question

This is the predicament I'm in:

  1. The ASP.NET MVC project I'm working on doesn't use the repository pattern.
  2. All DbContext the controller layer places calls
  3. DbContext is created as required for memory management reasons ONLY, NOT connection pool purposes, and is encapsulated in a using statement.
  4. These controllers need unit testing, therefore injecting theDbContext into the game console.
  5. We don't make use of IoC containers. I would need to create a fresh instance in a function Object() { [native code] } without parameters and utilise it for the duration of the call to the controller action.
  6. Most of these circumstances are beyond my control.

Conditions that I may modify:

  1. If a trustworthy alternative is available, remove the using statement.
  2. Admit that this code cannot be tested as is and divert your attention to anything else.

So, I have a question: How can I succeed in aDbContext to the function Object() { [native code] } in order to simulate the replies that are delivered while maintaining the validity of the using statement as they often conflict with one another.

If I need to quit using the, that's OK.using statement, provided there is a means to guarantee that the context is always destroyed after the specified action has been completed.

Any opinions on this?

1
0
6/1/2018 6:17:59 PM

Accepted Answer

You cannot test using a mocked dependent since creating a DbContext within a function that you'd want to test is identical to creating any other concrete instance of a dependency inside the code. Without modifying the code or the structure, the following possibilities immediately spring to mind:

  • Create an in-memory data source that EF may use for unit testing.
  • Create a database with a known state that can be restored in between test runs. (More of an integration test; not ideal for TDD, which calls for tests that can run rapidly and often.)
  • Due to the absence of DI/IoC, categorise it as "wasn't intended for unit testing."

Although messy, mocking a DbContext is possible. I would suggest include an IoC container like Autofac in the project once you have one mock-able. I'm unsure of the circumstances that would prevent you from introducing an IoC container, but if the team is concerned that doing so would be an all-or-nothing refactor and a major undertaking, I'd reassure them that it can be done with only minor project changes and without breaking any already-written code. If the code doesn't make use of a DI/IoC container, how else will you manage concrete dependencies except the DbContext? You may upgrade all dependencies and controllers gradually rather than replacing them all at once.

Existing controllers with default constructors won't be impacted after a container has been configured to resolve MVC Controllers. After that, you can register your DbContext with the container and modify your test controller so that its function Object() { [native code] } will take the context. You wouldn't need the IoC Container if it set the DbContext lifetime scope to, say, Instance per Request.using {} block. The mocked DbContext may then be provided by your tests, and the container will take care of managing the lifecycle of the context.

I just published an essay on the usage of Lazy dependencies /w Autofac to make creating tests for classes with numerous dependencies a breeze. This is related to developing unit-test friendly controllers/code using an IoC container. Check out the article at https://medium.com/@StevePy/writing-easily-testable-code-with-autofac-lazy-properties-f9c63457c8ce.

0
6/2/2018 12:13:58 AM

Popular Answer

ZZZ_tmp


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow