I have added a unit test to a mvc5 application manually. This is my business logic
public void AddTreatments(TreatmentView model)
{
using(var treatment = new TreatmentRepository())
{
var treat = new PhysiqueData.ModelClasses.Treatment()
{
treatmentID = model.treatmentID,
treatmentCost = model.treatmentCost,
treatmentDuration = model.treatmentDuration,
treatmentName = model.treatmentName
}
treatment.Insert(treat);
}
}
This is my repository used in the service layer
public class TreatmentRepository:ITreatmentRepository
{
private ApplicationDbContext _datacontext;
private readonly IRepository<Treatment> _treatmentRepository;
public TreatmentRepository()
{
_datacontext = new ApplicationDbContext();
_treatmentRepository = new RepositoryService<Treatment>(_datacontext);
}
public void Insert(Treatment model)
{
_treatmentRepository.Insert(model);
}
}
The next code is my actual unit test for my treatment and it is not working, please can I get some guidance on it. I googled a lot of things and still can't get it right.
[TestClass]
public class UnitTest1
{
[TestMethod]
public void AddingTreatmenttodatabase()
{
//var business = new TreatmentBusiness(new TreatmentRepository());
var treatment = new Treatment()
{
treatmentID = 1,
treatmentCost = 250,
treatmentDuration = 45,
treatmentName = "LowerBack"
};
var repositoryMock = new Mock<ITreatmentRepository>();
repositoryMock.Setup(x => x.Insert(treatment));
var business = new TreatmentBusiness(repositoryMock.Object);
business.AddTreatments(treatment);
repositoryMock.Verify(x => x.Insert(treatment), Times.Once());
}
}
So you're instantiating a mock of
ITreatmentRepository
, setting up some behaviour and injecting it into yourTreatmentBusiness
class. So far, so good.But then, in your
AddTreatments
method, you're instantiating a newTreatmentRepository
, instead of using the one injected in via the constructor.I'm assuming your constructor looks something like this:
In which case, your method should look like this:
Notice the usage of the field
repository
, as opposed to instantiating a new one.As per Jimmy_keen's suggestion, in order to ensure your repository is properly instantiated and accessible throughout your class, a factory is advisable.
There are several ways you can achieve a repository factory, either you hand crank a dedicated factory and inject that into your constructor, like so:
And that change the way you access your repository like so:
If you feel this is too heavy handed, you can opt for a method delegate (
Func<>
) and inject just a method that instantiates a newTreatmentRepository
.This would change your constructor like so:
And you would change your method like this:
The way you resolve that dependency is up to you, either do it manually and inject that delegate like this when instantiating your Business object:
or you can use one of the many IoC containers/DI frameworks out there.