I'm very new to the Unit Testing. Just Wanted to unit test existing webapi controller. Inside the controller, I'm resolving dependencies using UnityContainer.
While running the test case, getting an exception
Microsoft.Practices.Unity.ResolutionFailedException: Resolution of the
dependency failed
Can anyone guide me to resolve this dependency? Thanks in advance!!
public class PQController : ApiController
{
public IHttpActionResult GetById(int pqid)
{
if (!IsValidPqIds || sourceId <= 0)
{
return BadRequest();
}
IUnityContainer container = new UnityContainer();
container.RegisterType<IPQAdapter, PQAdapterDesktop>();
var pqDesktopAdapter = container.Resolve<IPQAdapter>();
var pq = pqDesktopAdapter.GetPQByIds<PQDesktop>(pqid);
return Ok(pq);
}
}
Test code:
[TestClass]
public class TestPriceQuoteController
{
[TestMethod]
public void Get_PriceQuoeById_Should_Return_Valid_PriceQuote()
{
var pqController = new PQController();
// Act
IHttpActionResult actionResult = pqController.GetById(55560);
var contentResult = actionResult as OkNegotiatedContentResult<PQDesktop>;
// Assert
Assert.IsNotNull(contentResult);
Assert.IsNotNull(contentResult.Content);
Assert.AreEqual(55560, contentResult.Content.PQId);
}
}
Related
This is my controller
BusinessLayer.Lookup.Lookup_Rooms RoomsBL = new BusinessLayer.Lookup.Lookup_Rooms();
[HttpPost]
public ActionResult CreateRoom(UMIS_Portal_BackEnd.Areas.StudentAcadimic.Models.RoomLocationModel room) {
if (ModelState.IsValid)
{
try
{
// TODO: Add insert logic here
int? Serial = RoomsBL.Lookup_RoomInsert(room.BuildingFloorID, room.RoomName, room.Min_Capacity, room.Max_Capacity);
}
catch (Exception error)
{
ViewBag.Messages = error.InnerException.Message;
}
}
return View();
}
I only want to test that there is view exist for this action result so i write this code
[TestMethod()]
public void CreateRoomTestPost()
{
LookupRoomsController controller = new LookupRoomsController();
UMIS_Portal_BackEnd.Areas.StudentAcadimic.Models.RoomLocationModel room = new UMIS_Portal_BackEnd.Areas.StudentAcadimic.Models.RoomLocationModel();
ViewResult viewResult = controller.CreateRoom(room) as ViewResult;
Assert.IsNotNull(viewResult);
}
I want the test to skip calling
int? Serial = RoomsBL.Lookup_RoomInsert(room.BuildingFloorID, room.RoomName, room.Min_Capacity, room.Max_Capacity);
on the main controller action.
The problem is that the controller is tightly coupled to implementation details
BusinessLayer.Lookup.Lookup_Rooms RoomsBL = new BusinessLayer.Lookup.Lookup_Rooms();
instead of having abstractions explicitly injected into it. It is not the controller's responsibility to create its dependencies. (Single Responsibility Principle (SRP) and Separations of Concerns (Soc))
The Lookup_Rooms needs to be abstracted
public interface ILookup_Rooms {
//...
}
public class Lookup_Rooms : ILookup_Rooms {
//...
}
and the abstraction explicitly injected into the controller.
private readonly BusinessLayer.Lookup.ILookup_Rooms RoomsBL;
//CTOR
public LookupRoomsController(ILookup_Rooms RoomsBL) {
this.RoomsBL = RoomsBL;
}
[HttpPost]
public ActionResult CreateRoom(RoomLocationModel room) {
if (ModelState.IsValid) {
try {
// TODO: Add insert logic here
int? Serial = RoomsBL.Lookup_RoomInsert(room.BuildingFloorID, room.RoomName, room.Min_Capacity, room.Max_Capacity);
} catch (Exception error) {
ViewBag.Messages = error.InnerException.Message;
}
}
return View();
}
That way a mocked one can be made to perform no action when Lookup_RoomInsert is invoked in an isolated unit test.
[TestMethod()]
public void CreateRoomTestPost() {
// Arrange
ILookup_Rooms mock = Mock.Of<ILookup_Rooms>(); //using MOQ
LookupRoomsController controller = new LookupRoomsController(mock);
RoomLocationModel room = new RoomLocationModel();
// Act
ViewResult viewResult = controller.CreateRoom(room) as ViewResult;
// Assert
Assert.IsNotNull(viewResult);
}
Finally, the abstraction and implementation should be registered with a DI container so that the actual implementation can be properly injected into the controller when the system is running in production.
I am needing to set up a Unit Test for our project. In our Controllers we are using a Unit of Work which holds all the repositories and calling the repository in our IHttpActionResult to get the data.
So far I have set up a Mock of the Interfaces and this is calling the correct IHttpActionResult in the Controller but there is no data coming back.
[TestMethod]
public void TestMethod1()
{
var unitOfWork = new Mock<IUnitOfWork>();
var repo = new Mock<IAuditReleaseRepository>();
unitOfWork.Setup(e => e.AuditReleaseRepository).Returns(repo.Object);
var auditReleaseController = new AuditReleaseController(unitOfWork.Object);
var result = auditReleaseController.Get() as ViewResult;
var model = result.ViewData.Model as IQueryable<AuditReleas>;
Assert.AreEqual(12, model.Count());
}
public class AuditReleaseController : BaseController
{
private IAuditReleaseRepository _auditReleaseRepository;
private IUnitOfWork _unitOfWork;
public AuditReleaseController(IUnitOfWork unitOfWork)
{
this._unitOfWork = unitOfWork;
this._auditReleaseRepository = unitOfWork.AuditReleaseRepository;
}
[HttpGet, Route("audit-releases")]
public IHttpActionResult Get()
{
var query = this._auditReleaseRepository.GetAll();
return Ok(query);
}
}
public class AuditReleaseRepository : RepositoryBase<AuditReleas>, IAuditReleaseRepository
{
private readonly RetailAssignmentEntities _entities;
public AuditReleaseRepository(RetailAssignmentEntities entities) : base(entities)
{
this._entities = entities;
}
IEnumerable<AuditReleaseDto> IDtoRepository<AuditReleaseDto>.GetAll()
{
return base.GetAll().Where(x=>x.IsReleaseEnabled).Select(AuditReleaseMapping.All).OrderByDescending(x => x.Id);
}
}
This is the Mapping that is taking place to get the data in the GetAll method:
public class AuditReleaseMapping
{
public static Expression<Func<AuditReleas, AuditReleaseDto>> All = (auditRelease) => new AuditReleaseDto()
{
EndDate = auditRelease.AuditReleaseEndDate,
Id = auditRelease.AuditReleaseId,
Name = auditRelease.AuditReleaseName,
StartDate = auditRelease.AuditReleaseStartDate,
AuditPeriodId = auditRelease.AuditPeriod.AuditPeriodId,
AuditYearId = auditRelease.AuditPeriod.AuditYear.AuditYearId,
AuditEndDate = auditRelease.AuditPeriod.AuditEndDate,
AuditStartDate = auditRelease.AuditPeriod.AuditStartDate
};
}
What would be ideal is to call the Controller, which would call the repository, which would then call the Mapping but so far it's not even calling the Repository to get the data. I need help getting that functionality set up.
It looks like you need to Setup the behavior for your Mock repo.GetAll(). You will need to create a list of AuditReleaseDto's for your Mocked repo to return. Call it TestAuditReleaseDtos. You can create this TestData in the beginning of your TestMethod or in the TesstClass initialization. Then use it in a line right after creating your Mock:
var repo = new Mock<IAuditReleaseRepository>();
repo.Setup(r => r.GetAll()).Returns(TestAuditReleaseDtos);
unitOfWork.Setup(e => e.AuditReleaseRepository).Returns(repo.Object);
I'm trying to test my project. I have never used tests before and I am starting to learn I would like a help, in the simplest case I want test this public ActionResult Index() but I don't know how to Inject those dependencies.
Controller:
Controller:
public class WorkPlacesController : Controller
{
private readonly IWorkPlaceService workPlaceService;
public WorkPlacesController(IWorkPlaceService workPlaceService)
{
this.workPlaceService = workPlaceService;
}
// GET: WorkPlaces
public ActionResult Index()
{
var workPlaces = workPlaceService.GetWorkPlaces(includedRelated:
true);
return View(workPlaces);
}
}
Here is my Service
Service
public class WorkPlaceService : IWorkPlaceService
{
private readonly IWorkPlaceRepository workPlacesRepository;
private readonly IUnitOfWork unitOfWork;
public WorkPlaceService(IWorkPlaceRepository workPlacesRepository, IUnitOfWork unitOfWork)
{
this.workPlacesRepository = workPlacesRepository;
this.unitOfWork = unitOfWork;
}
}
public interface IWorkPlaceService
{
IEnumerable<WorkPlace> GetWorkPlaces(string workPlaceDescription = null, bool includedRelated = true);
}
And my Repository
Repository
public class WorkPlaceRepository : RepositoryBase<WorkPlace>, IWorkPlaceRepository
{
public WorkPlaceRepository(IDbFactory dbFactory)
: base(dbFactory) { }
public WorkPlace GetWorkPlaceByDescription(string workPlaceDescription)
{
var workPlace = this.DbContext.WorkPlaces.Where(c => c.Description == workPlaceDescription).FirstOrDefault();
return workPlace;
}
}
public interface IWorkPlaceRepository : IRepository<WorkPlace>
{
WorkPlace GetWorkPlaceByDescription(string workPlaceDescription);
}
Factory
public class DbFactory : Disposable, IDbFactory
{
AgendaEntities dbContext;
public AgendaEntities Init()
{
return dbContext ?? (dbContext = new AgendaEntities());
}
protected override void DisposeCore()
{
if (dbContext != null)
dbContext.Dispose();
}
}
I tried to do something like this:
public void BasicIndexTest()
{
// Arrange
var mockRepository = new Mock<IWorkPlaceService>();
var controller = new WorkPlacesController(mockRepository.Object);
// Act
ActionResult actionResult = controller.Index() as ViewResult;
// Assert
Assert.IsInstanceOfType(actionResult, typeof(List<WorkPlace>));
}
How do I inject in this controller the data needed to go in the database and bring the results?
I Want test this public ActionResult Index() but I don't know how to Inject those dependencies.
Mock the behavior of required dependencies of the controller for the test and assert the desired behavior when the test is exercised.
For example, based on what you have done so far
public void BasicIndexTest() {
// Arrange
var mockService = new Mock<IWorkPlaceService>();
var workPlaces = new List<WorkPlace>() {
new WorkPlace()
};
mockService
.Setup(_ => _.GetWorkPlaces(It.IsAny<string>(), It.IsAny<bool>()))
.Returns(workPlaces);
var controller = new WorkPlacesController(mockService.Object);
// Act
var actionResult = controller.Index() as ViewResult;
// Assert
Assert.IsNotNull(actionResult);
var model = actionResult.Model;
Assert.IsNotNull(model)
Assert.IsInstanceOfType(model, typeof(List<WorkPlace>));
Assert.AreEqual(workPlaces, model);
}
Only the IWorkPlaceService was needed for the testing of Index action, but fake data was needed for the invocation of the GetWorkPlaces method. So the mock was configured to return a list of objects when called and pass it to the view result.
I'm a sitecore developer and I want to create a sample sitecore helix unit testing project for testing out our "HomeBottomContentController" controller:
public class HomeBottomContentController : GlassController
{
private readonly ISitecoreContext _iSitecoreContext;
public HomeBottomContentController(ISitecoreContext iSitecoreContext)
{
_iSitecoreContext = iSitecoreContext;
}
public override ActionResult Index()
{
var model = _iSitecoreContext.GetCurrentItem<Home_Control>();
return View("~/Views/HomeBottomContent/HomeBottomContent.cshtml", model);
}
}
I have created a WTW.Feature.HomeBottomContent.Tests project, for the purpose of testing this entire component using helix unit testing. In it I have a UnitTest1.cs file with following:
namespace WTW.Feature.HomeBottomContent.Tests
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void Test_ISitecoreContextInsertion()
{
var iSitecoreContext = Mock.Of<Glass.Mapper.Sc.ISitecoreContext>();
HomeBottomContentController controllerUnderTest = new HomeBottomContentController(iSitecoreContext);
var result = controllerUnderTest.Index() as ViewResult;
Assert.IsNotNull(result);
}
}
}
This test does pass, meaning "result" is NOT null; however, the problem is when I step into the Index() code, I see that the "model" variable is NULL when we do
var model = _iSitecoreContext.GetCurrentItem<Home_Control>();
My question is, how exactly do I change this code to make sure that the "model" in that line does not become null? How do I "mock" an item in unit test code for the _iSitecoreContext so that it has a "Home_Control" template with legit values for its fields? Would that even be the right approach? Most online sources I've found do not have a similar scenario, I'm looking for the shortest code possible.
Another question I had is, how can I test the below Index() method in my [TestMethod], given that the SitecoreContext is declared inside the Index() method, rather than received in the HomeBottomContentController constructor like above? Is there a way to do that from the [TestMethod], or we have to send in the SitecoreContext into the HomeBottomContentController constructor or into the Index() method as a parameter?
public override ActionResult Index()
{
var context = new SitecoreContext();
var model = context.GetCurrentItem<Home_Control>();
return View("~/Views/HomeBottomContent/HomeBottomContent.cshtml", model);
}
In that case you would need to mock the desired behavior on the mocked dependency
[TestClass]
public class UnitTest1 {
[TestMethod]
public void Test_ISitecoreContextInsertion() {
//Arrange
var model = new Home_Control() {
//...populate as needed
}
var iSitecoreContext = new Mock<Glass.Mapper.Sc.ISitecoreContext>();
//Setup the method to return a model when called.
iSitecoreContext.Setup(_ => _.GetCurrentItem<Home_Control>()).Returns(model);
var controllerUnderTest = new HomeBottomContentController(iSitecoreContext.Object);
//Act
var result = controllerUnderTest.Index() as ViewResult;
//Assert
Assert.IsNotNull(result);
Assert.IsNotNull(result.Model);
//...other assertions.
}
}
UPDATE
Creating the context within the action tightly couples it to the context, making it almost impossible to mock. That is the reason explicit dependencies are injected
You can do something like that:
public class HomeBottomContentController : GlassController
{
private readonly ISitecoreContext _iSitecoreContext;
public HomeBottomContentController(ISitecoreContext iSitecoreContext)
{
_iSitecoreContext = iSitecoreContext;
}
public override ActionResult Index()
{
var model = this.GetCurrentItem();
return View("~/Views/HomeBottomContent/HomeBottomContent.cshtml", model);
}
protected virtual Home_Control GetCurrentItem()
{
return _iSitecoreContext.GetCurrentItem<Home_Control>();
}
}
namespace WTW.Feature.HomeBottomContent.Tests
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void Test_ISitecoreContextInsertion()
{
var iSitecoreContext = Mock.Of<Glass.Mapper.Sc.ISitecoreContext>();
var controllerUnderTest = new FakeHomeBottomContentController(iSitecoreContext);
var result = controllerUnderTest.Index() as ViewResult;
Assert.IsNotNull(result);
}
}
public class FakeHomeBottomContentController : HomeBottomContentController
{
public FakeHomeBottomContentController(ISitecoreContext iSitecoreContext) : base(iSitecoreContext)
{
}
protected override Home_Control GetCurrentItem()
{
// return instance of Home_Control type
// e.g.
return new Home_Control();
}
}
}
I have a little experience working with Dependency Injection using Xamarin.Forms, but not in WebApi, What I want is send data through my Interface and execute inside of my Class which is implementing that Interface, there's what I have :
public interface IRepository
{
IHttpActionResult SendContext(user user);
IHttpActionResult GetContextData(int id);
}
public class ContextGoneBase : ApiController,IRepository
{
public IHttpActionResult GetContextData(int id)
{
try
{
using (var context = new GoneContext())
{
var result = context.user.Where(a => a.id_user == id).Select(w =>
new { w.user_name, w.cellphone_number, w.user_kind, w.CEP, w.area.area_name, w.district, w.city.city_name, w.city.state.state_name });
var list = result.ToList();
if (list != null)
{
return Ok(list);
}
else
{
return BadRequest();
}
}
}
catch (Exception)
{
return BadRequest();
}
}
And Inside of my controller I was trying to do something like that:
[Route("86538505")]
public IHttpActionResult GetData(int id, IRepository repo)
{
this._repo = repo;
var result = _repo.GetContextData(id);
return result;
}
But, it fails! Thanks!
You should instead pass the IRepository as a parameter to the constructor
Set the field _repo of type IRepository to the value of the parameter passed.
public ContextGoneBase (IRepository repository){ //Constructor
_repo = repository;
}
.And then use an IOC container like Unity to instantiate the controller with the right parameters.For example after you install Unity using nuget you will have a UnityConfig class file and there you can register your repository type.For example if your repository is of type Repository then
public static class UnityConfig
{
public static void RegisterComponents()
{
// register all your components with the container here
// it is NOT necessary to register your controllers
// e.g. container.RegisterType<ITestService, TestService>();
var container = new UnityContainer();
container.RegisterType<IRepository,Repository>();
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
}
}
Now in Global.asax call this method:
protected void Application_Start()
{
UnityConfig.RegisterComponents();
}