I just came across some existing code from an existing application and I'm trying to understand the first two lines in the unit test. Here is the unit test:
[TestMethod]
public void CanDisplayReportWithPage()
{
var claimComponent = new Mock<IClaimsComponent>();
GlobalContainer.Unity.RegisterInstance(claimComponent.Object);
_pharmacyCdmService
.Setup(service => service.ReadAllTenantEstablishments((It.IsAny<Guid>())))
.Returns(ResponseHelper.CreateResponse(new TenantEstablishmentDataContract[0]));
_pharmacyCdmService
.Setup(service => service.ReadTenantById((It.IsAny<long>())))
.Returns(ResponseHelper.CreateResponse(new TenantDataContract()));
claimComponent.Setup(
component => component.FileDetailsClaimReport(It.IsAny<RamqDetailsClaimReportRequestDataContract>()))
.Returns(new RamqDetailsClaimReportResponseDataContract());
var result = (ViewResult)_controller.View(new DetailsReportModel(), 3);
_pharmacyCdmService.VerifyAll();
_claimIdentityHelper.VerifyAll();
Assert.IsNotNull(result);
Assert.IsNotNull(result.Model);
Assert.AreEqual("Index", result.ViewName);
Assert.IsInstanceOfType(result.Model, typeof(DetailsReportModel));
Assert.AreEqual(2, ((DetailsReportModel) result.Model).DataContract.PageTransaction);
}
This test uses a combination of Moq and Unity. What I'm trying to understand is why the mocked instance (claimComponent) has to be registered with Unity.
My guess is the system under test uses the Service Locator anti-pattern. GlobalContainer is the key - it's probably a Singleton (generally another anti-pattern) that makes the IoC container available everywhere.
A better alternative would be to use constructor injection (probably with the controller) using Unity.MVC3 or equivalent. That lets you compose everything in one Composition Root. Your unit tests typically don't need to reference Unity at all; they can just create a mock and pass it to the controller.
Related
I've developed a CQRS style database access framework based on Tripod and other inspirations but targeting .NET Standard and simplifying for easier use. I want to split the IoC into separate integration packages so consumers can get the type registration I'm currently doing internally easily without being locked into a specific IoC container. My issue is I've only really worked closely with SimpleInjector so not familiar with other systems and their nuances around how they handle specific scenarios. I have an iminent need to support Autofac so thought I'd try here to see if anyone can translate.
I have the following Simple Injector CompositionRoot static class:
public static void RegisterDatabase(this Container container, DbContextOptions<EntityDbContext> dbContextOptions, params Assembly[] assemblies)
{
var scopedLifeStyle = container.Options.DefaultScopedLifestyle;
//container.Register<ICreateDbModel, DefaultDbModelCreator>(scopedLifeStyle); // lifestyle c
container.RegisterInitializer<EntityDbContext>( //(container.InjectProperties);
handlerToInitialise => handlerToInitialise.ModelCreator = new DefaultDbModelCreator()
);
// Setup DbContext
var ctxReg = scopedLifeStyle.CreateRegistration(
() => new EntityDbContext(dbContextOptions),
container);
container.AddRegistration<IUnitOfWork>(ctxReg);
container.AddRegistration<IReadEntities>(ctxReg);
container.AddRegistration<IWriteEntities>(ctxReg);
}
In ASP.NET Core solutions I invoke the above from Startup.Configure(...) with:
var optionsBuilder = new DbContextOptionsBuilder<EntityDbContext>()
//.UseInMemoryDatabase("Snoogans");
.UseSqlServer(_config.GetConnectionString("DefaultConnection"));
container.RegisterDatabase(optionsBuilder.Options);
which allows me to switch out to an in memory database for unit testing if needed. EntityDbContext contains all my unit of work methods for calling onto the context without having to specify explicit DbSet for each table. The IUnitOfWork, IReadEntities and IWriteEntities interfaces all define methods on the EntityDbContext.
So I'm not sure how I'd go about making an Autofac module that allows scoped registration of the dbcontext with passed in DbContextOptions followed by multiple registrations of interfaces to this registration.
Does anyone know how this can be achieved?
I worked out the process and now have an AutoFac module. I was able to registermodule by instance of the class and also pass in the options when I instantiate. Because EntityDbContext implements the three interfaces I was registering separately in the Simple Injector scenario, AutoFac has the convenience of being able to just infer them and register with AsImplementedInterfaces()
public class EntityFrameworkModule : Module
{
private readonly DbContextOptions<EntityDbContext> _dbContextOptions;
public EntityFrameworkModule(DbContextOptions<EntityDbContext> dbContextOptions)
{
_dbContextOptions = dbContextOptions;
}
protected override void Load(ContainerBuilder builder)
{
// If the calling code hasn't already registered a custom
// ICreateDbModel then register the internal DefaultDbModelCreator
builder.RegisterType<DefaultDbModelCreator>()
.IfNotRegistered(typeof(ICreateDbModel))
.As<ICreateDbModel>();
// Expecting IUnitOfWork, IReadEntities and IWriteEntities to be registered with this call
builder.Register(c => new EntityDbContext(_dbContextOptions)
{
ModelCreator = c.Resolve<ICreateDbModel>()
})
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
}
}
I'm trying to implement the Identity system in an ASP.NET Core app (RC2 libraries) and there is a particular hangup that is driving me crazy.
First of all, I am not using EntityFramework. I'm not even using SQL. I'm backing up to RavenDB, so I need the implementation to be very specific to that; Which isn't a problem.
So I designed a RavenUserStore class, and it looks like this;
public class RavenUserStore<TUser> :
IUserStore<TUser>,
IUserLoginStore<TUser>,
IUserPasswordStore<TUser>,
IUserRoleStore<TUser>,
IUserSecurityStampStore<TUser>,
IUserClaimStore<TUser>,
IUserLockoutStore<TUser>,
IUserTwoFactorStore<TUser>,
IUserEmailStore<TUser> {
// ...
}
Works great on its own. I've implemented all the methods, etc. It's wonderful. Very clean and efficient.
Now, I go over to my web application and wire things up;
services.AddTransient<ILookupNormalizer>(s => new LowerInvariantLookupNormalizer());
services.AddTransient<IPasswordHasher<Member>>(s => new PasswordHasher<Member>());
services.AddTransient<IUserStore<Member>, RavenUserStore<Member>>();
services.AddIdentity<Member, Role>(o => {
o.Password.RequiredLength = 6;
o.Password.RequireDigit = true;
o.Password.RequireLowercase = false;
o.Password.RequireUppercase = false;
})
.AddUserStore<RavenUserStore<Member>>()
.AddRoleStore<RavenRoleStore<Role>>();
So I go make a controller to use this, per all the samples I've seen, and the very core sample from the Identity Framework Github Repository
//... [PROPERTIES]...//
public AccountController(UserManager<Member> userManager, SignInManager<Member> signInManager) {
// ... [attach constructor parameters to properties] ...//
}
Alright, so I inspect the classes carefully.
UserManager<T> has a property Store,which is a type of IUserStore<T>.
So theoretically.. if the dependency injection resolves types of IUserStore<T> to RavenUserStore<T> when they are injected through a constructor.. shouldn't that mean that the UserManager<T> gets a RavenUserStore<T> as its Store property?
I thought it would too; But when I call methods on the UserManager, it DOES NOT call the ones on my RavenUserStore. Why is this? What can I do?
Do I really have to ALSO make a custom UserManager class and do all of those methods AGAIN?
You need to add your own custom providers before calling services.AddIdentity(). Internally, AddIdentity uses TryAddScoped() which only adds the default items if they don't already exist in the services container.
So just putting the call to AddIdentity() after you registered all your custom implementations should mean that they will take precedence as you expect.
I'm trying to follow this Get Started example for testing with Moq. I'm able to duplicate the examples within my own testing project and can get my tests to pass (testing my service where my context is injected). However, what I don't understand is WHEN to use each of the following Setup calls:
var mockSet = new Mock<DbSet<Blog>>();
mockSet.As<IQueryable<Blog>>().Setup(m => m.Provider).Returns(data.Provider);
mockSet.As<IQueryable<Blog>>().Setup(m => m.Expression).Returns(data.Expression);
mockSet.As<IQueryable<Blog>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockSet.As<IQueryable<Blog>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
Can someone explain in very basic terms as to when each of these should be used?
For example, It seems that if the method in my service that I'm testing uses an expression, I need to do the 2nd setup call above (I've done some trial and error by removing and re-inserting these calls). I've been to the Moq documentation as well as MSDN for Table-TEntity and I still don't see it. Perhaps because I don't have a strong grasp of the Linq namespace.
TL;DR - When using an Entity Framework DBContext dependency, you will need perform these Setups on any DBSet which you intend to mock, specifically to return fake data to any LINQ queries on the DBSet. All 4 setups should be done for each mocked DbSet - this can be done generically in a helper method.
In more Detail:
In general, with Strict mode off, Setup is only required on methods that you actually want to Mock. In this case, if you haven't done a Setup on a method which is invoked during your Unit Test, Moq will instead provide default behaviour for any method which hasn't been explicitly Setup, which typically is to return the default(T) of any expected return type, T. For classes, the default is null, which isn't really going to help any during testing of classes dependent on a Mocked EF DbContext.
The specific example you have provided is the standard mocked setup for an Entity Framework DbSet, which then allows you to provide fake data for this specific DbSet (DbSet<Blog>), by providing an alternative IQueryable<Blog> from a List<Blog> collection (as opposed to the usual concrete RDBMS implementation).
A suggestion would be to move the DbSetmock code into your standard unit test plumbing setup framework / toolkit, to create a helper method like:
public static Mock<IDbSet<T>> GetMockedDbSet<T>(IList<T> fakeData) where T : class, new()
{
var data = fakeData.AsQueryable();
var mockSet = new Mock<IDbSet<T>>();
mockSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(data.Provider);
mockSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(data.Expression);
mockSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
return mockSet;
}
Which you can then set up on your Mock DBContext, as follows:
var mockContext = new Mock<IMyDbContext>();
var mockBlogDbSet = GetMockedDbSet<Blog>(new List<Blog>{... fake data here ...});
mockContext.Setup(c => c.Blogs).Returns(mockBlogDbSet.Object);
var sut = new SomeClassIWantToTest(mockContext.Object); // Inject dependency into Ctor
sut.DoSomething();...
I'm struggling to find the correct way to unit test my symfony 2 services which use doctrine or other common services.
What i have done so far:
In my understanding the controller actions should:
be as short as possible
take the request
execute required methods from injected services
build a response out of this
is a service itself
To accomplish a lightweight action, i try to encapsule the logic into a separate service which gets injected into the controller.
This works nicely expect for testing everything.
Here my current code:
Controller
class SearchController
{
// search_helper, request and templating are controller-injected
protected $search_helper;
protected $request;
protected $templating;
// ...
public function searchAction()
{
$searchterm = strtolower($this->request->query->get('q'));
$result = $this->search_helper->findSamples($searchterm);
// Found a single result. Redirect to this page
if (is_string($result))
{
return new RedirectResponse($result, 301);
}
return new Response($this->templating->render('AlbiSampleBundle:Search:index.html.twig', array('results' => $result)));
}
}
SearchService
class SearchHelper
{
// doctrine, session and min_query_len are controller-injected
protected $doctrine;
protected $session;
protected $min_query_len;
// ...
public function findSamples($searchterm)
{
if (strlen($searchterm) < $this->min_query_len)
{
$msg = 'Your search must contain at least 3 characters!';
$this->session->getFlashBag()->add('error', $msg);
return false;
}
$em = $this->doctrine->getManager();
$results = $em->getRepository('AlbiSampleBundle:Sample')->findPossibleSamples($searchterm);
// Execute a more advanced search, if std. search don't delivers a result
// ...
return $results;
}
}
How can i test this code correctly?
The repository is tested with phpunit_db and a inmemory sqlite database ✓
The action can be tested through a simple functional test ✓
What's left is the logic in the search-service. e.g. the findSamples method
My first thought was to mock the dependencies (in fact that was one of the main aspects in separating the dependencies), but you not only have to mock the doctrine object, but also the entitymanager and the repository.
$em = $this->doctrine->getManager();
$results = $em->getRepository('AlbiSampleBundle:Sample')->findPossibleSamples($searchterm);
I think there must be a better solution. Not only would this mocking need many LOCs, it also doesn't feel right. The test would be unnecessarily coupled really tight to the SUT.
EDIT
Here is a sample test i came up with. Using mock objects.
The test won't work. I realized it would take much more mock-objects and i got the feeling this isn't the right way.
The test fails because SessionMock->getFlashbag doesn't return a flashbag with add method.
doctrine->getManager returns no EntityManager. The EntityManager has no getRepository method. And the repository is missing findPossibleSamples.
class SearchHelperTest extends \PHPUnit_Framework_TestCase
{
private $router;
private $session;
private $doctrine;
public function setUp()
{
parent::setUp();
// ...
}
public function testSearchReturnValue()
{
$search_service = $this->createSearchHelper();
$this->assertFalse($search_service->findSamples('s'));
}
protected function createSearchHelper()
{
return new SearchHelper($this->doctrine, $this->router, $this->session, 3);
}
protected function getDoctrineMock()
{
return $this->getMock('Doctrine\Bundle\DoctrineBundle\Registry', array('getManager'), array(), '', false);
}
protected function getSessionMock()
{
return $this->getMock('Symfony\Component\HttpFoundation\Session\Session', array('getFlashBag'), array(), '', false);
}
protected function getRouterMock()
{
return $this->getMock('Symfony\Component\Routing\Router', array('generate'), array(), '', false);
}
}
Hope the community can help me, writing well tested code :)
cheers
For your specific example I would argue that the validation of the $searchterm doesn't really belong in your service - at the very least a service should never depend on the session. There are ways you could move the session out of the service and leave the validation in but personally I would use symfony validation for this i.e. have a SampleSearchType for the form that uses itself as the data class and hang the validation off that in validation.yml (or using annotations as appropriate).
Once that validation is taken out, what's left from your question is another findX() method to be added to the repository (there's no reason why repository methods can't call and build on each other) which you already know how to test.
Having said that, I still agree that with Symfony there is a general issue of how to test services in isolation from injected services. With respect to testing in isolation from the persistence layer I've avoiding trying to do this so far. My business layer services are so tightly coupled with the persistence layer that the cost of trying to test them independently is not worthwhile (what logic there is consists mainly of making related db updates or sending emails for which symfony provides it's own decoupling mechanism). I'm not sure if this is because I'm doing it wrong or because the apps I'm working on are light on business logic!
To isolate service tests from dependencies other than persistence I've tried:
Overriding service classes with mocked versions in the configuration. Issue - you don't want to do this for functional tests which means you have to have tests scripts which update the configuration and/or change the config to run individual tests. Advantage - you can run the same test as an isolated unit test and as an integration test by flipping the config
(Warning: nasty hack!) providing a setter method to replace an injected service with a mocked version from the test program.
(Not yet tried) Directly instantiate the service being tested, passing mock dependencies in on construction.
With respect to isolating from the persistence layer the only approach that makes sense to me is to abstract it out of the service to be tested into a wrapper service which contains no additional logic. The wrapper service could then be mocked using one of the above approaches (or hopefully a better solution that someone else is going to suggest?!)
EDIT: to address the issue of complexity of mocking dependencies - very occasionally this may be unavoidable but in general this is an indication that the design needs revisiting. This is one of the strengths of TDD - it strongly encourages simplified design and decoupling of components:
No service should need to be dependent upon the session object. This is not good practice and can always be avoided. Worst case the example method could return mixed values and if the result is not an array it's assumed to be an error message, although there are better alternatives.
Sometimes dependencies are unnecessary (code more naturally belongs elsewhere) or too general (I would question the necessity of injecting high level objects like doctrine or e.g. the container into anything other than test helpers).
If there is a complex dependency to mock (such as on multiple classes from the persistence layer) abstract it out into a wrapper which is far simpler to mock than the complex dependency.
I want to implement IOC in my application but i am confused, in my application i have multiple concrete classes which implement an interface. Consider this scenario:-
I have an Inteface ICommand and following concrete types which implement this interface:-
AddAddress
AddContact
RemoveAddress
RemoveContact
Basically user performs all this action in UI and then List is passed to the service layer where each command is executed.
So in GUI layer I will write
ICommand command1 = new AddAddress();
ICommand command2 = new RemoveContact();
In command manger
List<ICommand> listOfCommands = List<ICommand>();
listOfCommands.Add(command1);
listOfCommands.Add(command2);
Then finally will pass listOfCommands to service layer.
Now as per my understanding of IOC is only one concrete class is mapped to the interface. And we use this syntax to get our concrete type from StructureMap container.
ICommand command = ObjectFactory.GetInstance<ICommand>();
How should i implement IOC in this scenario?
In this scenario you're better off making your commands into value objects, i.e. not created by the IoC container:
class AddAddressCommand {
public AddAddressCommand(string address) {
Address = address;
}
public string Address { get; private set; }
}
When you create a command, you really do want a specific implementation, and you want to parameterise it precisely, both concerns that will work against the services of the IoC container. This will become even more relevant if you decide at some point to serialize the command objects.
Instead, make the service-layer components that execute the commands into IoC-provided components:
class AddAddressHandler : IHandler<AddAddressCommand> {
public AddAddressHandler(ISomeDependency someDependency) { ... }
public void Handle(AddAddressCommand command) {
// Execution logic using dependencies goes here
}
}
In your case, the component that accepts the list of commands to execute will need to resolve the appropriate handler for each command and dispatch the command object to it.
There's some discussion of how to do this with Windsor here: http://devlicious.com/blogs/krzysztof_kozmic/archive/2010/03/11/advanced-castle-windsor-generic-typed-factories-auto-release-and-more.aspx - the community supporting your IoC container of choice will be able to help you with its configuration.
As mentioned by Mark, StructureMap will allow you to set up and call named instances of an interface:
ObjectFactory.Initialize(x =>
{
x.For<ISomeInterface>().Add<SomeImplementation>().Named("SomeName");
}
You can still add a default instance for that particular interface, of course:
ObjectFactory.Initialize(x =>
{
x.For<ISomeInterface>().Add<DefaultImplementation>();
x.For<ISomeInterface>().Add<SomeImplementation>().Named("SomeName");
}
When you call ObjectFactory.GetInstance<ISomeInterface>(); the default instance (the one initialized with Use instead of Add) is the one that will be returned.
So in your case, the set up would look something like:
ObjectFactory.Initialize(x =>
{
// names are arbitrary
x.For<ICommand>().Add<AddAddress>().Named("AddAddress");
x.For<ICommand>().Add<RemoveContact>().Named("RemoveContact");
}
These would be called as pointed out by Mark:
ObjectFactory.GetNamedInstance<ICommand>("AddAddress");
ObjectFactory.GetNamedInstance<ICommand>("RemoveContact");
Hope this helps.
Most IOC containers allow you to register "named instances" of interfaces, allowing you to register several implementations of ICommand, each with its own unique name. In StructureMap, you request them like this:
ObjectFactory.GetNamedInstance<ICommand>("AddAddress");
Have a look at this question to see how you setup the container in StructureMap.