I have a MVC3 project that uses property injection. Within my controllers I make a call to a service class. As I mentioned it uses property injection (with unity) instead of resolving this through the constructor. I have searched all over trying to find an example of a unit test that resolves these dependencies within my controller but everything seems to refer to constructer DI. I’m getting frustrated. Any help would be great.
Example of Controller:
[Dependency]
public ITrainingService trainingService { get; set; }
public ActionResult Index(MyTrainingView myTrainingView)
{
//Load all training items into view object
myTrainingView.training = trainingService.getTraining(myTrainingView.trainingId);
myTrainingView.videos = trainingService.getTrainingVideos(myTrainingView.trainingId);
myTrainingView.visuals = trainingService.getTrainingVisuals(myTrainingView.trainingId);
myTrainingView.exams = trainingService.getTrainingExams(myTrainingView.trainingId);
return View(myTrainingView);
}
I'm trying to resolve the trainingService when running my unit test. I have found countless examples for mocking and resolving dependencies using constructor dependency but nothing when it comes to property injection.
You don't need to rely on unity in your unit tests.
Something like this would do the trick:
[Test]
public void GetTrainingById()
{
var mockService = MockRepository.GenerateMock<ITrainingService>();
mockService.Stub(service => service.getTraining(123)).Return(new ImaginaryClass());
var sut = new TrainingController();
sut.trainingService = mockService;
var myTrainingView = new MyTrainingView();
sut.Index(myTrainingView);
Assert.AreEqual(expected, myTrainingView.training);
}
If you must use unity in your unit tests, you could just instantiate the UnityContainer in your test and use the RegisterInstance to register the objects you want to inject.
Related
I'm on .NET 4.6.2 and using the following versions of the assemblies via Nuget:
Service
Autofac - 4.8.1
Autofac.Extras.AggregateService - 4.1.0
Autofac.Wcf - 4.1.0
Castle.Core - 4.3.1
Tests
Autofac.Extras.Moq - 4.3.0
Moq - 4.10.1
The setup I'm using for the host container is exactly like the "Getting Started" example from the Docs and you end up with a proxy generated from DynamicProxy, and this works well by eliminating the constructor overloads.
When it comes to unit testing the services that use this type of injection I seem to be stumbling on how to mock it out properly.
I've spent a few hours trying various approaches and none of them have panned out. Here's basically what I have:
public interface IMyAggregateService
{
IFirstService FirstService { get; }
ISecondService SecondService { get; }
IThirdService ThirdService { get; }
IFourthService FourthService { get; }
}
public class SomeController
{
private readonly IMyAggregateService _aggregateService;
public SomeController(IMyAggregateService aggregateService)
{
_aggregateService = aggregateService;
}
}
using (var mock = AutoMock.GetLoose())
{
//var depends = mock.Mock<IMyAggregateService>().SetupAllProperties(); //Not working
//depends.SetupProperty(p => p.IFirstService, ?? );
//depends.SetupProperty(p => p.ISecondService, ?? );
//depends.SetupProperty(p => p.IThirdService, ?? );
//depends.SetupProperty(p => p.IFourthService, ?? );
var sut = mock.Create<SomeController>();
Action action = () => sut.SomeAction();
action.Should().xxxx
}
So the first problem I had was that there are no setters on the IMyAggregateService so the SetupProperty method won't work. When I used SetupAllProperties, everything was null at run-time, so that won't work. I even pulled down the Autofac.Extras.AggregateService code and was checking out the Test project, but there's really nothing I can gleam from it that might help, except the AggregateServiceGenerator might be useful at some point.
So my questions is,
"How do I properly mock an aggregate service, and provide behaviors for it during unit testing?"
For extra credit I'd like to know also how to provide a specific implementation of any of the dependencies that are properties, like this:
using (var mock = AutoMock.GetLoose())
{
mock.Provide<IFirstService>(this.MyImplProperty);
"How do I properly mock an aggregate service, and provide behaviors
for it during unit testing?"
Try to do smth like this (it is not using automoq just a moq :))
var firstServiceImpl= new Mock<IFirstService>();
var secondServiceImp2= new Mock<ISecondService>();
var myAggregateServie= new Mock<IMyAggregateService>();
myAggregateServie.SetupGet(x => x.FirstService ).Returns(firstServiceImpl);
myAggregateServie.SetupGet(x => x.SecondService ).Returns(secondServiceImp2);
.
.
.
And then you can mock behaviours of your services, and verify calls, some pseudo code will look like this.
//Mock as above
//Mock service behavior
firstServiceImpl.Setup(m=>m.Method1()).Returns(1)
//test method of you controller, lets assume that the method1 of controller
//is only calling firstService method named Method1()
var result = SampleController.Method1();
Assert.IsTrue( result == 1)
firstService.Verify(m=>m.Method1(), Times.Once()).
I recently took a .Net project over which exposes DAOs from a Microsoft SQL Database via ServiceStack(3.9.71) REST API. Since I am gonna refactor some parts I want to unit test (at least) all servicestack services. For a better understanding I quickly draft how the implementation works.
Each Service contains a property of type DBService which encapsulates all database accesses of all services. Unfortunately this is a concrete class which makes it hard to mock. The DI.Container wrappes ServiceStack's IOC.
public class SomeService : Service
{
public DBService { get { return DI.Container.Resolve<DBService>(); } }
public object Get(SomeDataClass class)
{
var response = DBService.SomeServiceGet();
return response;
}
// other code omitted
}
The DBService looks like this (draft):
public class DBService
{
public IDbConnectionFactory DBFactory { get { return DI.Container.Resolve<IDbConnectionFactory>(); } }
public SomeServiceResponse SomeServiceGet()
{
//DB Access here...
// ...
}
public SomeOtherServiceResponse SomeOtherServiceGet()
{
//...
}
// following about 30 other methods for all the services (POST,GET,PUT etc)
}
I read the detailed response to this question but I was not able to create and initialize a BasicAppHost in ServiceStack 3.9.71 since it immediately threw a System.TypeLoadExceptionMethod 'get_VirtualPathProvider'.
On the other hand I was thinking that I do not actually need a BasicAppHost. I just have to unit test the DBService and then the servicestack services with a somehow mocked DBService. The only problem I have is that DBService is not an interface and that I am actually not sure how to deal (mock) with the SQL database and the IOC.
[UPDATE]
Unfortunately I am still not able to test a service since I can not just new the service in my test. If I do so I get:
System.TypeLoadExceptionCould not load type 'ServiceStack.ServiceHost.IService' from assembly
Here is my test:
[Fact]
public void SomeDataTest()
{
var serviceUnderTest = new SomeService();
var response = serviceUnderTest.Get(new SomeDataClass());
Assert.NotNull(response);
}
I guess the problem is that the services strongly uses alot of properties which are injected via the IOC. How can I mock that? Creating a BasicAppHost and retrieving the service from there also does not work which I already mentioned.
If you are just testing your service class, then you can directly mock any dependencies:
[Fact]
public void SomeDataTest(
{
var serviceUnderTest = new SomeService();
var logger = new Mock<ILogger>(); // Rhino mocks fashion.
serviceUnderTest.Logger = logger.Object;
var response = serviceUnderTest.Get(new SomeDataClass());
Assert.NotNull(response);
}
There's an page in their older docs here about integration testing in case you want to test the AppHost
Edit: there's an example of mocking the service dependencies here.
I have no experience on writting Unit Tests and I am starting with it.
My project has a Data Access Layer (with nhibernate) where I have repositories that are injected by an IoC container into some Services in a Business Layer. I want to write Unit Tests to test some methods on the Services (business Layer). I know it is important to have Moqs to simulate the Repositories and avoid hits over the dataBase. I would like to know how to test this method:
public bool AddNewProject(ProjectViewModel viewModel)
{
// _projectRepository is an interface: IProjectRepository, resolved by IoC container
if (_projectRepository.ExistsNumber(viewModel.Number))
{
Validation.AddError("Number", GlobalResource.DuplicatedNumber);
return false;
}
if (_projectRepository.GetTotalAvailable(viewModel.ItemId) > 0)
{
Validation.AddError("ItemId", GlobalResource.NotItemAvailable);
return false;
}
var project = Mapper.Map<Project>(viewModel);
project.Data = _projectRepository.GetData(viewModel.ItemId);
_projectRepository.Save(project);
viewModel.Id = project.Id;
return true;
}
I know I have to write at least three unit tests, one for each validation and one for success. The problem is that in the AutoMapper configuration, I have my IoC container resolving a type the AfterMap event, for sample:
config.CreateMap<ProjectViewModel, Project>()
.AfterMap((vm, p) => {
// it is necessary because nhibernate will save this relation
var cityRepository = container.Resolve<ICityRepository>();
p.City = cityRepository.Load(vm.CityId);
});
I saw in some place on the web that it is not necessary to have the IoC container in the unit test and I should Moq just the methods I need (not sure if it is correct). Should I have to define memory repositories and register them on a ioc container on the test project? I would be difficult to test because i need to rewrite all the repositories (more than 300).
Obs: It is difficult to change because there are more than 300 entities using Repository.Load to make associations on the AfterMap event on the AutoMapper.
This is my unit test:
[TestMethod]
public void Should_not_save_a_project_by_existent_number()
{
var viewModel = new ProjectViewModel();
viewModel.Code = "PJT";
viewModel.CityId = 1;
viewModel.ItemId = 1;
viewModel.Name = "This is a test";
// for the validation, I use this simulator in memory (in asp.net mvc I encapsulate the ModelState)
var validator = new MemoryValidation();
var projectMoqRepository = new Mock<IProjectRepository>();
// I will mock methods here...
var projectService = new ProjectService(projectMoqRepository.Object, validator);
// the ICityRepository is defined on the IoC, so when I call AddNewProject
// it will be resolved inside the AutoMapper context on the AfterMap event.
// it is not injected on the ProjectService ctor.
var result = projectService.AddNewProject(viewModel);
projectService.Validation["Number"].ShouldNotBeEmpty();
result.ShouldBeFalse();
}
I am exploring CodeCamper project by JohnPapa on github
https://github.com/johnpapa/CodeCamper. This is a ASP.Net SPA application and I am also working on similar project.
I interested to write some UnitTests for WebAPI controller. Controller contractor requires UnitofWork instanse and UnitofWork is initiate in Application_Start method.
When I run my UnitTest project UnitofWork object is null. How I can initiate UnitofWork from UnitTest project so that I can run my test methods. I hope make myself clear.
Here is a sample UnitTest method for following controller.
LookupsController.cs
UserControllerTest.cs
[TestClass]
public class UserControllerTest : ApiBaseController
{
[TestMethod]
public void GetRoomsTest()
{
var controller = new LookupsController(Uow);
var result = controller. GetRooms().Any();
Assert.IsTrue(result);
}
}
Again why Uow is null? What should I do, so that I can write unit test methods for this type of project/architecture.
For more detail about code you can check github repo.https://github.com/johnpapa/CodeCamper
Use any mocking framework to create a fake/stub/mock for ICodeCamperUow (below I am using NSubstitute):
[TestMethod]
public void GetRoomsTest()
{
// UOW we need to use
var fakeUOW = Substitute.For<ICodeCamperUow>();
// setting up room repository so that it returns a collection of one room
var fakeRooms = Substitute.For<IRepository<Room>>();
var fakeRoomsQueryable = new[]{new Room()}.AsQueryable();
fakeRooms.GetAll<Room>().Returns(fakeRoomsQueryable);
// connect UOW with room repository
fakeUOW.Rooms.Returns(fakeRooms);
var controller = new LookupsController(fakeUOW);
var result = controller.GetRooms().Any();
Assert.IsTrue(result);
}
Please consider reading The Art of Unit Testing which is a great book to learn about unit testing.
I am trying to use the fluent test helpers to test an AbstractRestfulFluentController
public class CustomerController : AbstractRestfulFluentController
{
private readonly IService<Customer> _customerService;
private readonly IService<CustomerAddress> _addressService;
public CustomerController(IService<Customer> customerService, IService<CustomerAddress> addressService)
{
//Assume we use these in other actions
_customerService = customerService;
_addressService = addressService;
}
public ActionResult Index()
{
return View();
}
}
As you can see I am injecting some services into the controller and resolving them using IOC. My problem is that all the examples I have found using the fluent test methods in mvccontrib don't work without a paramaterless controller.
public void SuccessfulIndex()
{
GivenController.As<CustomerController>()
.ShouldRenderItself(RestfulAction.Index)
.WhenCalling(x => x.Index());
}
I'm not sure what I need to do in order to be able to use IOC with the fluent test techniques in mvccontrib. I have found a few comments that it is possible but haven't found anything. What can I do in order to actually use IOC and fluent tests?
You could write a method which allows you to provide the instance of the controller:
public static class GivenController
{
public static ActionExpectations<T> As<T>(T controller) where T: Controller, new()
{
return new ActionExpectations<T> { MockController = controller };
}
}
And then in your unit test:
var controller = CreateMockedCustomerController();
GivenController
.As<CustomerController>(controller)
.ShouldRenderItself(RestfulAction.Index)
.WhenCalling(x => x.Index());
The requirement is that the controller should be a mock object which in my opinion is not a very clean approach (testing a mocked object). You could create it like this:
var controller = MockRepository
.GeneratePartialMock<CustomerController>(new object[] { dep1, dep2 });
Notice how dependencies are passed to the constructor.
Have you tried property injection instead of constructor injection?
http://ninject.codeplex.com/wikipage?title=Injection%20Patterns
I am currently having a weird ninject issue that I just posted about, but this should at least point you in the right direction...all the code is there for setting up the dependency injection.
https://stackoverflow.com/questions/3909452/unit-testing-asp-net-mvc-controllers-with-ninject