I'm trying to learn dependency injection and have come across a problem, when unit testing the application.
I'm writing a console application and the container is created and initialized in Main(), it's available as a get-property
in Program.Container
, so anywhere in my application I can call Program.Container.Resolve<..>()
.
I have a ServiceValidator class like this:
public class ServiceValidator
{
private readonly IConfiguration _configuration;
private readonly IService _service;
public ServiceValidator(IConfiguration configuration, IService service)
{
_configuration = configuration;
_service = service;
}
In another class I use
ServiceValidator serviceValidator = Program.Container.Resolve<ServiceValidator>();
serviceValidator.VerifyVersion();
It's the call to Program.Container.Resolve
that causes me problems in the unit test, as it hasn't been setup.
Is that a bad practice, to call resolve on the container? I could create the ServiceValidator instance in Main()
and pass the object around, but that seems stupid as it would cause lots of parameters for the objects that are just passed around to the next method.
So I guess it's acceptable to call Resolve within a class, but then the container must be configured for the unit test. How should I do that, should I move the container to another place than the Program class? What would you recommend?
If it matters, I'm using Unity and C#
Thanks :-)
Dependency injection helps if you have a class that needs a dependent class-instance to do some sub-processing. Instead of DI you can seperate the logic of a business-method into a data-gethering-part (that is not unit-testable) and a calculation part that can be unit-tested.
Angular services can be tested in a couple of different ways, two most prominent being isolated tests and using the Angular TestBed . However, things get interesting when the service under test has dependencies (injected using Angular's dependency injection).
While both add value to the development process, they are different in many ways. End-to-end testing is a testing process in which the tester tests a software application from the user's perspective. Unit testing is a testing process where the developer verifies that individual units of source code work correctly.
Is that a bad practice, to call resolve on the container? I could create the ServiceValidator instance in Main() and pass the object around, but that seems stupid as it would cause lots of parameters for the objects that are just passed around to the next method.
When you use dependency injection all the way, then you won't need to pass lots of parameters to objects. The constructor of each object should have as parameters only those dependencies which it itself uses directly - it won't know about the transitive dependencies of its direct dependencies.
So if you have a class X which requires a ServiceValidator, then class X will have a constructor parameter of type ServiceValidator. Then if some class Y uses class X, then class Y will have a constructor parameter of type X. Notice that Y knows nothing about ServiceValidator, so you don't need to pass the ServiceValidator from one class to another - the only place where it is used is when constructing X, and that is often done by a DI framework or in only one place in a hand-written factory.
Some links for more information:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With