aspnetcore: ConfigureTestContainer not working with GenericHost
Describe the bug
When using GenericHost
, in tests ConfigureTestContainer
is not executed.
To Reproduce
I’ve added a test in https://github.com/alefranz/AspNetCore/commit/282c153cfd343498928636780558031f0ab940b2#diff-589b0cebe9e796b47e521f0318393df2R194-R208 to reproduce
Expected behavior
The delegate provided with ConfigureTestContainer
should be executed
Additional context
This happen in 3.x
I’m looking at providing a fix for this but I would probably need some hint on the right place to address this. Could you also confirm the behavior is not intentional?
@Tratcher I’ve seen you have worked to add support to ConfigureTestServices
with GenericHost
in https://github.com/aspnet/AspNetCore/pull/6585/files#diff-48af505b9d348e7e52da534c4590aef1R36 - Do you think it would need a similar logic to address this as well?
Thank you, Alessio
About this issue
- Original URL
- State: open
- Created 5 years ago
- Reactions: 45
- Comments: 62 (20 by maintainers)
OK waking up and re-reading this issue. IT does seem like a bug that should be fixed and potentially patched though it is risky (maybe it’ll need to be quirked). I will follow up with some people.
All due respect, I am sorry but the provided answers to this issues are simply not satisfactory.
This does not work, as demonstrated in Tratcher’s post here: https://github.com/aspnet/AspNetCore/issues/14907#issuecomment-542388201
@javiercn 's description in https://github.com/aspnet/AspNetCore/issues/14907#issuecomment-541011786 implies to be the intended behaviour is that
Startup.ConfigureContainer
should be called afterProgram.ConfigureContainer
if the later is called afterUseStarup
. This is not the case which means it is a plain bug.None of the technique above are working, meaning that there is no apparent nor easy workaround. I’m excluding @cdibbs 's techniques which prevents testing in parallel.
This issue prevents from having a proper way for tests to override dependencies, which is a huge issue for us (and I suspect many other). We have tons of tests doing exactly that and this bug prevents us from moving from 2.1 to 3.1
This is a big show-stopper for anyone who wants to properly test his application.
I have the exact same issue. Is there a workaround that would allow us to bypass this issue?
@cdibbs no changes are planned for 3.1.
Here is a workaround for Autofac that will call any
ConfigureTestContainer(...)
method, also in.WithWebHostBuilder(...)
calls.It builds on @ssunkari’s workaround
Usage
This workaround* of creating a derived
TestStartup
from @RehanSaeed is working for us: https://rehansaeed.com/asp-net-core-integration-testing-mocking-using-moq/*I describe it as a workaround as it would be nicer not to have to make
Configure
andConfigureServices
onStartup
virtual
.You can override container registrations in the following way, using Autofac as example:
Configure your container in
Program
instead ofStartup.ConfigureContainer(ContainerBuilder)
:Override container registrations using ContainerBuilder in a derived WebApplicationFactory:
@GODBS I ended up going the super-hacky route, for now. I hope this is fixed in 3.1.
@anurse this is really unfortunate… We have a lot of narrow integration tests that are redefining some of the dependencies and swapping them with mocks - calls to services. This bug prevents us from migrating as-is and implies a lot of refactoring, starting with something clean and ending with something ugly. I’m puzzled that something like that was overlooked, after all DI and testing are supposed to be an integral part of this product.
This is a pickle, I agree with @forktrucka that nobody seems to have this working. On the other hand I can see why you don’t want to patch and possible break hypothetical implementations, but here we are with all the 2.x implementations irremediably breaking when going to 3.x
I got it working by implementing custom factory for my container setup. In my case its Autofac. I have tweaked the IServiceProviderFacotry<ContainerBuilder> implementation of Autofac library.
Code
Test Setup
public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup:class {
} Refer to Autofac docs https://autofaccn.readthedocs.io/en/latest/integration/aspnetcore.html for service registration
I tried this. Seemed to face the same problem in my implementation… What am i missing?
Using 3.1, we’re using autofac and calling ConfigureContainer(ContainerBuilder builder) from startup. This seems to execute in the same order…
I would replace overriding
TestWebApplicationFactory
class with an action for added flexibility, like this:Then, my test method which resides inside an NUnit test fixture which needs to instantiate
TestWebApplicationFactory
class looks like this:One can employ
WithMockServices
only when needing to replace a registered service with something else, e.g. a class which will throw an exception whenever one of its methods are called, like in my above example.The full source code can be found here .
@jr01’s workaround prevents update to Autofac 6.0.0 because they sealed their
ContainerBuilder
. Therefore a fix would still be appreciated here.Cleanest solution I could achieve based on previous answers:
Create overrides:
Create new ServiceProviderFactory:
Use new Factory:
To wrap this up, Alistair tweaked the workaround provided by @jr01 to also work with the sealed
ContainerBuilder
of Autofac >= 6.0.0. So we can await .NET 5.0 without having to worry that it would break our integration tests.This issue always makes me facepalm… love ASP.NET Core but I can’t figure out why this is such a painful experience. Feel like we’re so close to being the number one web framework. Especially with Blazor RTM.
It’s been twice in three weeks that I’ve found myself coming back to this post to try and remember the workaround for this issue. I’ll try and turn it into a blog post so people can have a reference for how to remedy the situation until it’s fixed. I wouldn’t want people to not write tests 😉
I agree with @Pvlerick that my workaround doesn’t work when you run the tests in parallel (which is the norm). So, is my workaround really “viable?” Maybe not.
It sounds like any fix would have side effects, but perhaps that just builds a case for doubling up on the normal amount of testing done for a patch like this.