Reputation: 456
Trying to teach myself SimpleInjector and I grasp the basics but need some assistance.
Essentially I want to pass an object through simple injector which I have already populated rather than a new object.
The example Case I have is as follow:
ITeaService:
public interface ICup
{
string CupName { get; set; }
List<string> Ingredients { get; set; }
}
public class Cup : ICup
{
public string CupName { get; set; }
public List<string> Ingredients { get; set; }
}
public interface ITeaService
{
ICup GetTea();
}
TeaService:
public class TeaService : ITeaService
{
private ICup _cup;
public TeaService(ICup cup)
{
_cup = cup;
}
public ICup GetTea()
{
this._cup.Ingredients.Add("Tea bag");
this._cup.Ingredients.Add("Hot water");
return this._cup;
}
}
Test:
var container = new SimpleInjector.Container();
container.Register<ITeaService, TeaService>();
container.Register<ICup, Cup>();
container.Verify();
// Act
var cp = container.GetInstance<ICup>();
cp.CupName = "Daniel";
var teaService = container.GetInstance<ITeaService>();
var cup = teaService.GetTea();
Any thoughts how I pass a pre-defined Cup through? Is the variable cp where i've specified a CupName?
Upvotes: 0
Views: 343
Reputation: 99
container.RegisterSingleton<ICup>(standardCup)
is obsolete in v5.
But, you can use the following instead :
container.RegisterInstance<ICup>(standardCup);
Upvotes: 0
Reputation: 28747
The following line is incorrect:
container.Register<ICup, Cup>();
Here you're telling SimpleInjector to create a new Cup
whenever an ICup
is requested. Change it to the following to always return the same Cup
:
var standardCup = new Cup();
standardCup .CupName = "Daniel";
container.RegisterSingleton<ICup>(standardCup );
Now this test will succeed:
var teaService = container.GetInstance<ITeaService>();
var cup = teaService.GetTea();
Assert.AreEqual(cup.CupName, "Daniel");
Assert.AreEqual(cup, standardCup);
EDIT: Based on comments: If you always want a new instance, but with the same name, you can do the following:
container.Register<ICup>(() => new Cup { CupName = "Daniel"});
This will run the callback to construct a Cup
each time you request an ICup
Upvotes: 3
Reputation: 6335
the first question for you is what is it you are actually testing?
The way you wrote the test you are testing that SimpleInjector works not that your code works.
you need a test which uses a class which implements that interface because you need real code to test anything.
What I would do is this :
You really want your test to be valuable and test real functionality away from DI and IOC which are guaranteed to work anyway.
Makes sense? You're testing the Cup class and more than likely the service class, real classes not abstractions of them which by definition have no functionality and thus nothing to test.
Imagine what happens when you have 2 classes which implement ICup. You would write two test classes, one for each implementation.
More details added based on comment
your test is way more simpler then.
All you have to do is test that once you add an ingredient it actually appears in the Ingredients list of the Cup object. This means you only need to test the Cup class, the service doesn't do anything for you at this point in time. Test the simplest interactions you can, once those work you can keep moving to more complicated things, step by step.
So write the CupTests class. test that when you add an ingredient it actually appears in the ingredient list, check for errors and boundary errors like what happens when the Ingredients list is null when you try to add something to it.
That's all you need based on what you've shown thus far.
Upvotes: 0