I'm working on a design that will allow me to mock out my database so I can test my views. I don't want to read a full book on IOC because I don't have the time right now. So, this is my home cooking.
Controller:
public ActionResult Milestone()
{
var result = SJMServiceFactory.GetService("Milestone");
return View(result);
}
Factory:
public static class SJMServiceFactory
{
public static DatabaseCollection_Result<T> GetService(string serviceName)
{
switch(serviceName)
{
case("Milestone"): return MileStoneService.GetMilestone();
case ("MilestoneMock"): return MileStoneService.GetMilestone(true);
default : return default(T);
}
}
}
MileStone
public class MileStoneService
{
public MileStoneService()
{
}
public static DatabaseCollection_Result<Milestone> GetMilestone(bool Mock)
{
if (Mock)
{
DatabaseCollection_Result<Milestone> mileStones = new DatabaseCollection_Result<Milestone>();
Milestone milestone1 = new Milestone();
milestone1.Name = "New";
Milestone milestone2 = new Milestone();
milestone2.Name = "Assessment";
mileStones.Results.Add(milestone1);
mileStones.Results.Add(milestone2);
return mileStones;
}
else
return null;
}
}
I figure I need to return an interface from my factory instead of that Generic type I tried and failed at doing. I don't know how to create an interface that works for all my models, is that the wrong direction?
Without reading a whole book (does one exist? IoC is a pretty small topic in the scheme of things):
Controller:
private readonly IMilestoneService milestoneSerivce;
public MilestoneController(IMilestoneService milestoneService)
{
this.milestoneService = milestoneService;
}
public ActionResult Milestone()
{
var result = milestoneService.GetMilestones();
return View(result);
}
IMilestoneService.cs
public interface IMilestoneService
{
DatabaseCollection_Result<Milestone> GetMilestones();
}
MilestoneService.cs
public class MilestoneService : IMilestoneService
{
public DatabaseCollection_Result<Milestone> GetMilestones()
{
return null;
}
}
MockMilestoneService.cs:
public class MockMilestoneService : IMilestoneService
{
public DatabaseCollection_Result<Milestone> GetMilestones()
{
DatabaseCollection_Result<Milestone> mileStones = new DatabaseCollection_Result<Milestone>();
Milestone milestone1 = new Milestone();
milestone1.Name = "New";
Milestone milestone2 = new Milestone();
milestone2.Name = "Assessment";
mileStones.Results.Add(milestone1);
mileStones.Results.Add(milestone2);
return mileStones;
}
}
Global.asax:
ObjectFactory.Configure(x => {
x.For<IMilestoneService>().Use<MilestoneService>();
// uncomment for test
//x.For<IMilestoneService>().Use<MockMilestoneService>();
});
This uses StructureMap, but I imagine the Ninject way to wiring up the dependencies is similar. Having never used Ninject I don't know for sure, but it looks like it might be something like:
Bind<IMilestoneService>().To<MilestoneService>();
In general though I wouldn't go about creating a whole new class to test your Views, I would use a mocking framework such as Moq to create mock objects and pass them to the View and then use Assertions about the ViewResult to determine if it worked correctly.
If you're doing interactive testing though and want to be detached from the database, this might be an ok approach.
Don't fear the learning curve. IoC is a reasonably simple concept.
Ninject was the first container I picked up, and it went smoothly. The only point I really struggled with for any amount of time was how to organize all the bindings, but even that was only an issue in large applications.
YMMV, but I'd say just diving in with Ninject or similar is better investment of time than DIY.
IoC with Ninject only takes code in a few places.
1: Bind you interfaces to implementations:
public class ServiceModule : NinjectModule
{
public override void Load() {
Bind<Common.Billing.AuthorizeNet.IBillingGatewayParametersFactory>().To<AuthorizeNetParameterFactory>();
Bind<Common.Billing.IBillingGateway>().To<Common.Billing.AuthorizeNet.BillingGateway>();
}
}
2: Use constructor arguments to pass dependencies into a class:
public class BillPayingService
{
private readonly IBillingGateway _billingGateway;
public BillPayingService(
IBillingGateway billingGateway
)
{
_billingGateway = billingGateway;
}
public void PayBills()
{
// ....
}
}
3: Initialize your container on application startup:
public static class Ioc
{
public static void Initialize()
{
var modules = new INinjectModule[] {
new ServicesModule(),
new DataModule()
new VideoProcessing.NinjectModule()
};
IKernel kernel = new Ninject.StandardKernel(modules);
}
}
Related
I am trying to learn dependency inversion and IOC. In the process, I have hit a wall.
This is what I understand about DI principle -> high-level classes are based on abstractions and not implementations.
All good.
So keeping the above in mind. I have the following example.
public interface IServiceA
{
public void DoSomething();
}
public class ServiceA : IServiceAInterface
{
IDataInterface dataSource;
DataSourceType data;
// omitted config injectino for brevity
public ServiceA(IDataInterface _data)
{
dataSource = _dataSource;
var dataSourceName = config.GetValue<string>("DataSourceName");
data = dataSource.GetDataSource(dataSourceName);
}
public void doSomething()
{
data.doSomething();
}
}
public interface IDataInterface
{
public DataSourceType getDataSource(string ds);
}
public class DataAccessService : IDataInterface
{
public DataSourceType GetDataSource(string dataSource)
{
if (dataSource == "InApp")
{
var source = new DataSourceType();
return source;
}
else
{
return null;
}
}
}
The above is a service class which needs data to perform tasks which it gets from DataAccessService.
Now I am using an application class/model for persistence throughout the app lifetime. Therefore I have registered it as a singleton.
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
---
services.AddSingelton<IDataInterface,DataAccessService>();
service.AddScoped<IServieAInterface,ServiceA>();
---
}
This does not work.
I hypothesize it is because, the parent service (service A) has a lesser lifetime than the child service (DataAccessService).
I have understood through this that service A is responsible for instantiation of the object.
However, I expected the IOC container to instantiate only one DataAccessService object and inject it to all services that need this.
Not sure why my assumption is wrong.
Based on the above hypothesis I tried the following:
public interface IDataInterface
{
}
public class DataAccessService : IDataInterface
{
public DataSourceType dataSource;
public DataAccessService(string ds)
{
if (ds == "InApp")
{
this.dataSource = new DataSourceType();
}
else
{
this.dataSource = null;
}
}
}
public class ServiceA: DataAccessService,IServceAInterface
{
DatSourceTye data;
public ServiceA():base("InApp")
{
config = _config;
data = dataSource;
}
public void doSomething()
{
data.doSomething();
}
}
Startup.cs
// Hoping to pass parameter through startup
services.AddSingleton<IDataInterface>(x =>
ActivatorUtilities.CreateInstance<DataAccessService>(x, "InApp")
);
service.AddScoped<IServieAInterface,ServiceA>();
I hoped the above would work, as here the DataAccessService is responsible for initialization.
But still a new DataAccessService object is created for every class.
I think, I have messed up my understanding about how the life times work.
need help on this.
Also, what I am trying to achieve is a singleton data source on which different services act on throughout the application lifetime.
Transient and scoped services consuming a singleton data source. I think this should be possible
Is there something bad in terms of design in what I am trying to achieve?
public DataAccessService(string ds)
{
if (ds == "InApp")
{
this.dataSource = new DataSourceType();
}
else
{
this.dataSource = null;
}
}
This method in the data service was being called every time, I needed the data source.
As this method is instantiating another class manually, though the service is singleton,
every time the above method - DataAccessService was called , I was getting a new instance.
I want to give a caller of my class ability to choose provider by name, instead of passing the provider concrete class as standard DI recommends. It will allow to hide actual implementation details from client, still giving control which provider to use. We've done it by implementing factory
public ICurrencyProvider GetCurrencyServiceProvider(string providerName)
{
switch (providerName)
{
case "CurrencyLayerAPI":
{ currencyService = new CurrencyLayerWrapper(); }
break;
case "XE":
{ currencyProvider = new XEWrapper(); }
break;
}
return _currencyProvider;
}
and constuctor expects providerName as a parameter.
However for unit tests I wish to use Substitute, not concrete class of provider.
I ended up with 2 parameters, responsible for the same choice- name for production code and interface for calls from tests.
public CurrencyProcessor(string providerName, ICurrencyProvider substituteCurrencyProvider =null)
{
if(!providerName .IsNullOrEmpty())
{
_currencyProvider = GetCurrencyServiceProvider(providerName);
}
else
{ _currencyProvider =substituteCurrencyProvider;
}
}
Slightly alternative implementation is to read providerName from configuration instead of passing it as a parameter.
public CurrencyProcessor(IConfigurationProvider configurationProvider, ICurrencyProvider substituteCurrencyProvider =null)
{
_providerName = _configurationProvider.GetAppSetting("CurrencyProviderToUse");
if(!providerName .IsNullOrEmpty())
{
_currencyProvider = GetCurrencyServiceProvider(providerName);
}
else
{ _currencyProvider =substituteCurrencyProvider;
}
}
I wander, is any better way exist to have single parameter to control creation of internal object, but avoiding giving responsibility to create object to a client.
Related discussions
How to use Dependency Injection without breaking encapsulation?
Preferable way of making code testable: Dependency injection vs encapsulation
https://softwareengineering.stackexchange.com/questions/344442/dependency-injection-with-default-construction
since in your constructor your are statically creating your provider, just inject the provider.
create a factory as you describe....
public class CurrencyFactory
{
public static ICurrencyProvider GetCurrencyServiceProvider(string providerName)
{
return null;
}
}
then use standard dependency injection :-
public class CurrencyProcessor
{
private ICurrencyProvider _currencyProvider;
public CurrencyProcessor(ICurrencyProvider currencyProvider)
{
_currencyProvider = currencyProvider;
}
}
and then use like so
var p = new CurrencyProcessor(CurrencyFactory.GetCurrencyServiceProvider("bitcoin"));
then in your test mock it
var mock = new Mock<ICurrencyProvider>(). // mock stuff
Not sure if I understand it correct.
For me it sounds like you want to have 2 different Factories.
First create a Interface:
public interface ICurrencyProviderFactory
{
ICurrencyProvider Create()
}
Then create a Configuration Factory:
public class ConfigurationCurrencyProviderFactory : ICurrencyProviderFactory
{
public ConfigurationCurrencyProviderFactory(IConfigurationProvider configuration)
{
}
public ICurrencyProvider Create()
{
}
}
And then a UnitTest Factory:
public class UnitTestCurrencyProviderFactory : ICurrencyProviderFactory
{
public UnitTestCurrencyProviderFactory()
{
}
public ICurrencyProvider Create()
{
}
}
Your currency processor should look like this:
public CurrencyProcessor(ICurrencyProviderFactory factory)
{
_currencyProvider = factory.Create();
}
In your ServiceCollection or whereever you resolve your dependencies you should include the correct factory.
So for Production, you add the ConfigurationCurrencyProviderFactory, for UnitTest the UnitTestCurrencyProviderFactory. Your actual code then should depend on ICurrencyProviderFactory.
What you actually need to apply along with your factory is the Strategy Pattern
interface ICurrencyProvider {
//...members
}
public interface ICurrencyProviderStrategy {
string Name { get; }
ICurrencyProvider Create();
}
public interface ICurrencyProviderFactory {
ICurrencyProvider GetCurrencyServiceProvider(string providerName);
}
An implementation of the factory would depend on a collection of strategies to call upon to create the desired types.
public class CurrencyProviderFactory : ICurrencyProviderFactory {
private readonly IEnumerable<ICurrencyProviderStrategy> strategies;
public CurrencyProviderFactory(IEnumerable<ICurrencyProviderStrategy> strategies) {
this.strategies = strategies;
}
public ICurrencyProvider GetCurrencyServiceProvider(string providerName) {
var provider = strategies.FirstOrDefault(p => p.Name == providerName);
if (provider != null)
return provider.Create();
return null;
}
}
This would allow greater flexibility as any number of strategies can be injected.
Here is an example of a CurrencyLayerWrapper Strategy
public class CurrencyLayerWrapperProvider : ICurrencyProviderStrategy {
public string Name { get { return "CurrencyLayerAPI"; } }
public ICurrencyProvider Create() {
return new CurrencyLayerWrapper();
}
}
Is it possible to create a class under test with FakeItEasy, where all dependencies that are declared in the constructor are initialized automatically with fakes?
Imagine the class:
public class Inserting
{
public Inserting(
ITransactionService transactionService,
ISharedData sharedData)
{
TransactionService = transactionService;
SharedData = sharedData;
}
public ITransactionService TransactionService { get; }
public ISharedData SharedData { get; }
public void Enter()
{
TransactionService.StartTransaction();
}
}
Then I am creating all fake-objects in the test setup and construct my class under test with those fakes:
public class InsertingTest
{
private Inserting _inserting;
private ISharedData _fakeSharedData;
private ITransactionService _fakeTransactionService;
[SetUp]
public void SetUp()
{
_fakeTransactionService = A.Fake<ITransactionService>();
_fakeSharedData = A.Fake<ISharedData>();
_inserting = new Inserting(_fakeTransactionService, _fakeSharedData);
}
[Test]
public void TestEnter()
{
// Arrange
// Act
_inserting.Enter();
// Assert
A.CallTo(() => _fakeTransactionService.StartTransaction().MustHaveHappened();
}
}
But I saw in the Java-world, that when using Mockito and Dagger 2, you can do something like this:
public class PhoneDialer {
private Activity activity;
private PhoneCallListener phoneCallListener;
#Inject
public PhoneDialer(Activity activity, PhoneCallListener phoneCallListener) {
this.activity = activity;
this.phoneCallListener = phoneCallListener;
}
}
public class PhoneDialerTest {
#Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
#Mock
PhoneCallListener phoneCallListener;
#Mock
Activity activity;
#InjectMocks
PhoneDialer dialer;
#Test
public void test_dialer() throws Exception {
// Arrange
// Act
dialer.callNumber("abc");
// Assert
Mockito.verify(phoneCallListener, times(1)).startCall();
}
}
and the mocked classes are initialized automatically with fakes. Is there an equivalent procedure or function in C# with FakeItEasy?
I think you want something like
Automatically inject fakes in test fixture with FakeItEasy. You use [Fake] to mark fakes to inject and [UnderTest] to mark the production type to test.
We really should put this into the documentation.
Alternatively,
AutoFixture has an AutoFixture.AutoFakeItEasy module,
there's Autofac FakeItEasy integration, and also
Ninject FakeItEasy integration
I saw 'Automatically inject fakes in text fixture with FakeItEasy' and my initial reaction was surprise that it differed from my preconception, mainly because it needs 'intrusive' changes that attribute the test code... but perhaps that is an overreaction.
The FakeAttribute and UnderTestAttribute do force what is potentially a good structural constraint on your test (and system) design...
[FWLIW, before googling this, I had imagined the following:
containerBuilder.RegisterAsFakeCallingBaseType<SystemUnderTest>();
You can do something like this with Autofac's registration sources.
using Autofac;
using Autofac.Core;
using Autofac.Core.Activators.Delegate;
using Autofac.Core.Lifetime;
using Autofac.Core.Registration;
using FakeItEasy;
using Xunit;
public interface IDependOnSomething { }
public class IImplementThat : IDependOnSomething { }
public class CanIResolveIt
{
public CanIResolveIt(IDependOnSomething it)
{
}
}
public class FakeRegistrationSourceTest
{
[Fact]
public void BasicTest()
{
var container = new ContainerBuilder();
container.RegisterTypes<IImplementThat>().As<IDependOnSomething>();
container.RegisterSource(new FakeRegistrationSource<CanIResolveIt>());
var c = container.Build();
var theFake = c.Resolve<CanIResolveIt>();
Assert.NotNull(theFake);
}
}
public class FakeRegistrationSource<T> : IRegistrationSource
where T : class
{
public bool IsAdapterForIndividualComponents => false;
public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
{
var swt = service as IServiceWithType;
if (swt == null || !typeof(T).IsAssignableFrom(swt.ServiceType)) // TODO: is this the right way around?
{
return Enumerable.Empty<IComponentRegistration>();
}
var registration = new ComponentRegistration(
Guid.NewGuid(),
new DelegateActivator(swt.ServiceType, (context, #params) =>
{
List<object> v = new List<object>();
foreach (ParameterInfo p in typeof(T).GetConstructors().Single().GetParameters())
{
v.Add(context.Resolve(p.ParameterType));
}
return A.Fake<T>(that => that.CallsBaseMethods().WithArgumentsForConstructor(v));
}),
new CurrentScopeLifetime(),
InstanceSharing.None,
InstanceOwnership.OwnedByLifetimeScope,
new[] { service },
new Dictionary<string, object>());
return new IComponentRegistration[] { registration };
}
}
Main advantage of this approach is that it knows how to instantiate fake objects subclassing classes with constructor parameters, and inheriting their default behavior, when they have a single constructor (choosing intelligently from multiple constructors would be an obvious challenge that I'm not going to tackle...)
An obvious drawback is explicit registration every time you want something faked. AutoFake and so on offer ways to overcome that with faking of just about everything by default, which might well be what you want... and you can override it if not.]
I have a service defined like this:
public class MentorService : IMentorService
{
private readonly Func<MentorContext> _dbFactory;
public MentorService(string connectionString)
{
this._dbFactory = () => new MentorContext(connectionString);
}
public MentorService()
{
this._dbFactory = () => new MentorContext();
}
public MentorContext CreateContext()
{
return _dbFactory.Invoke();
}
public IList<User> GetUsers()
{
using (var db = CreateContext())
{
return db.Users.ToList();
}
}
// etc etc
}
Within my API controllers, I have the following:
public class UserController : ApiController
{
private readonly IMentorService _mentorService;
public UserController()
{
_mentorService = new MentorService();
}
public UserController(IMentorService mentorService)
{
_mentorService = mentorService;
}
}
I'd like to break the service up into sub-services for easier maintenance and testing - something like UserService, BookService, etc. Then I just want to use a single service in my controllers.
How can this be done?
I am a huge fan of factories for this sort of thing.
(Please note, I am assuming you have some sort of DI/IoC setup, considering you have an interface-based example)
Basically, you first split your code into separate classes UserService, BookService, etc. Once you've done that, you create a factory that creates these services for you. Something like this:
public class UserControllerServiceFactory : IUserControllerServiceFactory {
public IUserService CreateUserService() {
return _container.Get<IUserService>();
}
public IBookService CreateBookService() {
return _container.Get<IBookService>();
}
// etc.
}
We use Ninject for our DI/IoC, and prefer to use the Factories extensions for Ninject. This means we don't have to implement the factories ourselves.. we only define the interfaces.
Then you have the factory injected into your controller:
public UserController(IUserControllerServiceFactory factory) {
_factory = factory;
}
And then, your Action Methods use the factory to access the services you require:
[HttpGet]
public ActionResult ViewAllBooks() {
return View(_factory.CreateBookService().GetAll());
}
etc.
I hope that is what you meant.
I'm new to AutoFixture and am trying to create a friendly extension on my test context for the less TDD-inclined devs in the team. Here is the code:
public class HomeController : Controller
{
private readonly ISomeService _someService;
public HomeController(ISomeService someService)
{
_someService = someService;
}
public ActionResult Index()
{
_someService.SomeMethod();
return View("Index");
}
}
public class ControllerContext<T> where T : Controller
{
protected static T ControllerUnderTest;
private static IFixture _fixture;
public ControllerContext()
{
_fixture = new Fixture().Customize(new AutoMoqCustomization());
_fixture.Customize<ControllerContext>(c => c.Without(x => x.DisplayMode));
ControllerUnderTest = _fixture.Create<T>();
}
protected static Mock<TDouble> For<TDouble>() where TDouble : class
{
//var mock = _fixture.Create<TDouble>();
var mock = _fixture.Create<Mock<TDouble>>();
return mock;
}
}
So the extension is the For method - When I inspect ControllerUnderTest which has an injected 'ISomeService' it has an instance injected just fine, and it definitely calls the method I am asserting against. When I inspect the mock created in the 'For' method it appears to be the same version as the one injected to the controller, but it won't Verify!
public class EXAMPLE_When_going_to_home_page : ControllerContext<HomeController>
{
Because of = () =>
{
ControllerUnderTest.Index();
};
It should_do_something = () =>
{
//This throws a 'Invocation was not performed'
For<ISomeService>().Verify(x => x.SomeMethod());
};
Establish context = () =>
{
};
}
I am struggling to find any examples of someone doing something similar, I know I am definitely doing something stupid here but in my head this test should pass?
Create creates a new anonymous instance every time, unless you froze (via .Freeze<T>() or AutoFixture.Xunit's [Frozen]) an instance. That means that the value that is injected into HomeController is different from the one returned by For.
There are several possible solutions, all of which ultimately will involve Freezing the value or Injecting the one to use.
One example would look like this:
public class ControllerContext<T> where T : Controller
{
private static Lazy<T> _controllerFactory;
private static IFixture _fixture;
public ControllerContext()
{
_fixture = new Fixture().Customize(new AutoMoqCustomization());
_fixture.Customize<ControllerContext>(c => c.Without(x => x.DisplayMode));
_controllerFactory = new Lazy<T>(() => _fixture.Create<T>());
}
protected static Mock<TDouble> For<TDouble>() where TDouble : class
{
var mock = _fixture.Freeze<Mock<TDouble>>();
return mock;
}
protected static T ControllerUnderTest
{
get { return _controllerFactory.Value; }
}
}
public class EXAMPLE_When_going_to_home_page : ControllerContext<HomeController>
{
static Mock<ISomeService> SomeService;
Because of = () =>
{
SomeService = For<ISomeService>();
ControllerUnderTest.Index();
};
It should_do_something = () =>
{
//This throws a 'Invocation was not performed'
SomeService.Verify(x => x.SomeMethod());
};
Establish context = () =>
{
};
}
The important point of this changed version is that first Freeze is called on the service mock and only after that the anonymous instance of the controller is created. Because of the way the For method is now used, you should probably rename it to GetService.
You'll ultimately end up in a world of pain if you go down the road of having static state as a way of managing the interaction between the services and the SUT. One reason is for example that unit tests should be parallelizable (e.g. xUnit.net v2 but ultimately all test frameworks as it just makes sense)
You can add Customizations to AutoFixture to allow natural creation of MVC Controllers as needed and then it's just a matter of feeding in or Freezing customized dependencies as necessary.
I'd strongly suggest taking the time to change your structure of your tests to have AutoFixture creating the Controller declaratively - have a look at what's possible with AutoFixture.Xunit and use that to inform how you structure the test helpers you're using in your Specs.
(Some background - I've been around the houses with all this Spec stuff using SubSpec and ultimately ended up much happier with AutoFixture.Xunit - it's just simpler and more composable.