✅ Problems with mocking a ServiceProvider
So, for an integration test I want to create a substitute for the general service provider my application uses.
The service provider is used to create a scope in a constructor/ factory.
This is a minimal code example that showcases the issue:
On the last line I get the error:
30 Replies
Is the reasoning here being you want to change some registrations when running the integration tests or do you absolutely need to mock IServiceProvider's functions?
If the reasoning is the former then you could probably get away with overriding
ConfigureWebHost
in your WebApplicationFactory
and registering the dependencies there via builder.ConfigureTestServices(...
I am not sure I understand your initial question, but let me present why I need
CreateScope()
.
The project uses the actor model. The actor provider (basically a factory) has these:
Thus, I need some way to mock the scope and context for those functions to work.
Indeed, in the actual program (not the test), those work right after the WebApplicationBuilder is created (var builder = WebApplication.CreateBuilder(args);
)
Are you saying that I should go one level deeper in my test and create a substitute/ mock for the builder?i dont get why you're mocking the service provider
make a new service provider in your tests
but this is hardly an integration test if you're mocking/picking/choosing what actually functions as part of the test.
@Savage have you read this?
Microsoft.AspNetCore.Mvc.Testing
provides some really handy tools for integration testing including WebApplicationFactory which makes it easy to mock services for your testsIntegration tests in ASP.NET Core
Learn how integration tests ensure that an app's components function correctly at the infrastructure level, including the database, file system, and network.
Hmm I read it and what I want to test isn't as broad as integration tests are described there.
I can't describe it simply as a unit test either as two classes/ subsystems are involved.
However, for the test(s) in question, no database or web server are needed.
In that case I'd do what @Patrick mentioned and just create a real service provider with your mock services registered into it and pass that to the sut that requires IServiceProvider
Ook, so then I need to have an WebApplicationBuilder like in the actual program, right?
Nah you can forget all of that if this is a unit test
ServiceCollection sc = new ServiceCollection();
ServiceProvider = sc.BuildServiceProvider();
If I am not missing something (and I looked for it multiple times in the past few days), in the actual program the service provider is initialized when the builder is created. That is what confused me when it came to creating the service provider myself :d
Stack Overflow
How can I add services after build IServiceProvider?
These are some definitions:
public interface IClassA
{
} public class ClassA : IClassA { public ClassA() { Init(); } private void Init() { Console.WriteLi...
} public class ClassA : IClassA { public ClassA() { Init(); } private void Init() { Console.WriteLi...
If you're unit testing I assume you are not building the WebApplication, just creating the system under test directly?
So you can pass your own ServiceProvider in to it
Yes.
I think this might work, thanks!
Unknown User•15mo ago
Message Not Public
Sign In & Join Server To View
I realized that can't work as I need
If the serviceProvider is not a substitute, I can't use .Returns() on it.
Unknown User•15mo ago
Message Not Public
Sign In & Join Server To View
I don't want the real thing here, I want the one I manually defined in the test.
Unknown User•15mo ago
Message Not Public
Sign In & Join Server To View
Thanks, I need some time to internalize this as it is pretty different from everything else I have seen until now.
Hmm. I still ran into a problem: the
ActorProvider
constructor takes an IServiceProvider
instance as an argument.
Thus, to create a substitute for it, I first need to have serviceProvider
initialized.
Thanks for the insightful response however and the tips! I realize my problem might be too specific/ niche without (especially without full context).
Have a great day! 😄
Also, I have to apologize. I was told this before and that is what I should've done. My bad for not paying attention.Unknown User•15mo ago
Message Not Public
Sign In & Join Server To View
Some other things clicked for me and I am working on those now.
Is it ok if I leave this here for now?
Unknown User•15mo ago
Message Not Public
Sign In & Join Server To View
Unknown User•15mo ago
Message Not Public
Sign In & Join Server To View
To post C# code type the following:
```cs
// code here
```
Get an example by typing
$codegif
in chat
If your code is too long, post it to: https://paste.mod.gg/Unknown User•15mo ago
Message Not Public
Sign In & Join Server To View
Oh no, I know how to send code 😄
I meant "I am doing something else now, might come back to this discussion later if it is ok"
In another server I moderate, it is considered somewhat disrespectful to leave while receiving support.
Unknown User•15mo ago
Message Not Public
Sign In & Join Server To View
you're unit testing .NET at that point......
if you need stubbed custom implementations without a mocking library this is going to get you on your way.
otherwise there exists NSubstitute which you could use to make a more "testable" implementation where you can stipulate what returns, when and verifying returns.
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.