I have defined ISpecimenBuilder for my models and use it like that:
new Fixture().Customize(new ModelCustomization());
I want to use it in most of my tests concerning model. I also want to apply some form of post-processing in one of my test classes. Specifically I want to fill property CompanyHistory of all created Offers. It feels like it could be done like that:
fixture.Build<Offer>()
.With(o => o.CompanyHistory, _previouslyCreatedCompanyHistory)
.Create();
But Build<T> disables all customizations and I need them.
Can I do something like that?
fixture.Build<Offer>()
.WithCustomization(new ModelCustomization()) // there is no such method, but i'd like it to be
.With(o => o.CompanyHistory, _previouslyCreatedCompanyHistory)
.Create();
Or should I write my own Behavior? If so, can someone provide me with guidelines on doing that?
EDIT:
I feel I have to stress out that I want to use both my common customization (ModelCustomization) and Postprocessor
EDIT 2:
What I meant from the beginning is that ModelCustomization can (and should) create Offer and my to-be postprocessor should use that already created specimen and fill some of its properties.
Here is how you can create and use a Postprocessor in this case:
[Fact]
public void Test()
{
var fixture = new Fixture();
// (You may also include other customizations here.)
fixture.Customizations.Add(
new FilteringSpecimenBuilder(
new Postprocessor(
new MethodInvoker(
new ModestConstructorQuery()),
new OfferFiller()),
new OfferSpecification()));
var offer = fixture.Create<Offer>();
// -> offer.CompanyHistory has the value supplied in OfferFiller command.
}
The OfferFiller command is defined as:
internal class OfferFiller : ISpecimenCommand
{
public void Execute(object specimen, ISpecimenContext context)
{
if (specimen == null)
throw new ArgumentNullException("specimen");
if (context == null)
throw new ArgumentNullException("context");
var offer = specimen as Offer;
if (offer == null)
throw new ArgumentException(
"The specimen must be an instance of Offer.",
"specimen");
Array.ForEach(offer.GetType().GetProperties(), x =>
{
if (x.Name == "CompanyHistory ")
x.SetValue(offer, /*value*/);
else
x.SetValue(offer, context.Resolve(x.PropertyType));
});
}
}
The OfferSpecification is defined as:
internal class OfferSpecification : IRequestSpecification
{
public bool IsSatisfiedBy(object request)
{
var requestType = request as Type;
if (requestType == null)
return false;
return typeof(Offer).IsAssignableFrom(requestType);
}
}
I had a similar problem and have tried solutions mentioned here, but they didn't work as expected. Finally, I've found an implementation of a PostProcessWhereIsACustomization class, that does exactly what I needed:
AutoFixture customization to allow insertion of arbitrary postprocessing logic a la Customize( c=>c.Do()) but in a global manner Revised for v3 (initally for v2)
May save somebody some Googling.
I ended up writing following Customization:
private class OfferWithCompanyModelCustomization: ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new FilteringSpecimenBuilder(new Postprocessor(
new ModelSpecimenBuilder(), new FillModelPropertiesCommand()), new ExactTypeSpecification(typeof(Offer))));
}
private class FillModelPropertiesCommand : ISpecimenCommand
{
public void Execute(object specimen, ISpecimenContext context)
{
var offer = specimen as Offer;
offer.CompanyHistory = (CompanyHistory)context.Resolve(typeof(CompanyHistory));
}
}
}
This works, but it's far from perfect. As you can see, I refer to ModelSpecimenBuilder directly, so I'm dependent on implementation (as postprocessor I'd like not to be).
Answer posted by #Nikos is not satisfying, because his customization ignores previous customizations in chain of responsibility.
When we invoke the Create method, a CompositeSpecimenBuilder will invoke the Create method of all its contained builders until one of them provides a specimen. At this point the request is considered to be satisfied, and the rest of the builders are ignored.
source: AutoFixture Documentation
Related
Hi I am using Ninject in a Xamarin MVVM project. What I am trying to do is to bind specific implementations based on a enum type:
var foo = new Ninject.Parameters.Parameter("type", VMType, true);
Kernel.Get<ICommonComponentVM>(foo);
and the provider:
public class ICommonComponentVMProvider : Provider<ICommonComponentVM>
{
protected override ICommonComponentVM CreateInstance(IContext context)
{
//return the implementation based on type
}
}
which is binded in the Kernel Module as:
public class CoreModule : NinjectModule
{
public override void Load()
{
Bind<ICommonComponentVM>().ToProvider<ICommonComponentVMProvider>();
}
}
How can I extract the custom parameter from the binding IContext?
Or is this the correct way to do this? The Ninject wiki lacks this info.
EDIT
I arrived at
var param = context.Parameters.Single((arg) => arg.Name == "type");
but accessing the value of the parameter with param.GetValue needs two arguments: IContext and ITarget. I have the context but what should I put as Target?
In the meantime it works with null:
var type = (CommonVMTypes)param.GetValue(context, null);
so it looks like this:
protected override ICommonComponentVM CreateInstance(IContext context)
{
var param = context.Parameters.Single((arg) => arg.Name == "type");
if (param == null){
return null;
}
var type = (CommonVMTypes)param.GetValue(context, null); //<-- Needs an Action ITarget
switch (type)
// ...
}
You can access the parameters by the property ICollection<IParameter> IContext.Parameters. You can find it by using context.Parameters.Single(x => x.Name == "type").
You could also subclass Parameter or implement IParameter for a custom parameter type with strongly typed information, p.Ex. ComponentVMTypeParameter and then select it using context.Parameters.OfType<ComponentVMTypeParameter>().Single().
Alternative approaches:
use conditional bindings (When(...) syntax, can check for parameters, too) instead of the providers. Does not require extending the provider.
use a factory instead of a provider.
using named bindings:
Bind<IFoo>().To<Foo1>().Named("Foo1")
IResolutionRoot.Get<IFoo>("Foo1");
However, in principle there's no need to use an IProvider. You could instead
However, if there's a limited amount of types I'd consider using an abstract factory instead
I have something like this in almost every action:
public ActionResult Show(int object_id)
{
Object obj = ObjectRepository.ById(object_id);
if (obj == null)
{
throw new HttpException(404);
}
if (obj.SomeCheck)
{
throw new HttpException(403);
}
// processing
}
Question is how to move object getting (and throwing http exceptions) away from action and have something like this:
public ActionResult Show(Object obj)
{
// processing
}
UPD: Can't change ObjectRepository and model itself, it's used not only with ASP.NET but in other parts of the project.
One option is to refactor your boilerplate into a private method:
private object GetItem(object obj) {
Object obj = ObjectRepository.ById(object_id);
if (obj == null) {
throw new HttpException(404);
}
if (obj.SomeCheck()) {
throw new HttpException(403);
}
return obj;
}
Then:
public ActionResult Show(int object_id) {
object obj = GetItem(object_id);
// processing
}
As others have suggested you could write filters or invoke an AOP framework like PostSharp.
However, that might be a tall order for some. You might want to consider writing something simple, maintainable and fairly readable, that everyone on the team can immediately understand:
public ActionResult Show(int object_id)
{
SomeClass obj = Require<SomeClass>(object_id, assumption: o => o.SomeCheck);
// processing
}
//Perhaps: put this in a base controller or other common class
private object Require<T>(int id, Func<object, bool> assumption) where T : class
{
var o = ObjectRepository.ById(object_id) as T;
//Result is required
if (o == null) {
throw new HttpException(404);
}
//Verify assumption
if (!assumption(o)) {
throw new HttpException(403);
}
return o;
}
You might look at
Writing a custom filter attribute such as an AuthorizationAttribute or ValidateInputAttribute. They can be applied to the entire controller or to specify methods (actions). See http://msdn.microsoft.com/en-us/magazine/dd695917.aspx#id0070026 for an overview.
You might want to look at using PostSharp (Aspect-Oriented Programming framework) to inject suitable aspects into your methods.
Others have provided some good answers. Among them, I like the idea of using an action filter but unfortunately I don't believe it will work very well as you'll be forced to use property injection (or explicit instantiation - yuck!) for the repository, which I'd prefer to avoid. For this reason, I think a dedicated controller method is a better option.
I will throw one more idea in the hat, though.
You mentioned that you can't change ObjectRepository but you can always abstract it:
public class HttpObjectService /*: IObjectService */
{
private readonly /*I*/ObjectRepository _repository;
public HttpObjectService(/*I*/ObjectRepository repository)
{
if (repository == null) throw new ArgumentNullException("repository");
_repository = repository;
}
public Object ById(int id)
{
var obj = _repository.ById(id);
/* Check and throw HttpExceptions */
}
}
Then inject this into your controller. Whether or not you like the idea of a "web-specific" service that throws HttpExceptionsdirectly is a matter of taste but it is extremely reusable and, in this case, I believe it provides a cleaner separation of concerns than private validation methods in the controller.
The downside, of course, is that you're allowing your controller to delegate its responses (in the event of an error) directly to a third party. You may prefer your controller to have absolute control over this - that would be a reasonable criticism. In that case, you could always pass an ObjectValidator object into the constructor from the controller, which takes care of the validation. This would let your controller maintain control of what exceptions are thrown regardless of the service implementation.
You would have to be considerate of where this fits into your project architecture - it would probably belong in a separate assembly to your MVC project but one that is dedicated to web-based UIs.
I have a set of working imperative code in test and I'm trying to boil it down to an essential test convention.
My test looks like the following:
[Theory, BasicConventions]
public void GetVersionOnSiteVersionControllerReturnsASiteVersion(IFixture fixture)
{
fixture.OmitAutoProperties = true;
SiteVersion expected = fixture.Create<SiteVersion>();
SiteVersion actual = null;
var sut = fixture.Create<SiteVersionController>();
var response = sut
.GetSiteVersion()
.ExecuteAsync(new CancellationToken())
.Result
.TryGetContentValue<SiteVersion>(out actual);
actual.AsSource().OfLikeness<SiteVersion>().ShouldEqual(expected);
}
I also have a customization that allows this to work, namely by setting the HttpConfiguration and HttpRequestMessage to default non-null values.
public class ApiControllerCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
var origin = fixture.OmitAutoProperties;
fixture.OmitAutoProperties = true;
var sut = fixture.Create<SiteVersionController>();
sut.Configuration = fixture.Create<HttpConfiguration>();
sut.Request = fixture.Create<HttpRequestMessage>();
fixture.Inject<SiteVersionController>(sut);
fixture.OmitAutoProperties = origin;
}
}
First, this looks ugly, but if I use Build<>().omit().with(config).with(request), it shuts off the automoq customization which it needs to build those instances.
Second, this only works for a SiteVersionController. I'd much rather generalize this for all my ApiControllers (maybe that's a bad idea, but I won't know until I try).
Essentially my convention would be as follows:
for all ApiControllers, create them without auto properties but do set the http configuration and request message properties to default non-null values
ApiControllers are quite difficult to wire up, because you'll need to assign certain properties to them in order for everything to work. At the very least, you'll need the Request property to be assigned, because otherwise, the Controller can't invoke Request.CreateResponse. Thus, switching off auto-properties for ApiController instances isn't a good strategy. Instead, you can configure AutoFixture to wire up HttpRequestMessage instances correctly.
Web API 1
With ASP.NET Web API 1, I usually use a Customization like this:
public class WebApiCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customize<HttpRequestMessage>(c => c
.Do(x =>
x.Properties.Add(
HttpPropertyKeys.HttpConfigurationKey,
new HttpConfiguration())));
}
}
Since auto-properties are on by default, this is going to assign an appropriate instance of HttpRequestMessage to ApiController.Request. Together with an Auto-mocking Customization, Fixture can now create instances of all your ApiController classes.
Web API 2
With ASP.NET Web API 2 (5.0.0.0), things are a little more complicated, but with a bit of trial and error, I got this Customization to pass 808 tests:
public class WebApiCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customize<HttpConfiguration>(c => c
.OmitAutoProperties());
fixture.Customize<HttpRequestMessage>(c => c
.Do(x =>
x.Properties.Add(
HttpPropertyKeys.HttpConfigurationKey,
fixture.Create<HttpConfiguration>())));
fixture.Customize<HttpRequestContext>(c => c
.Without(x => x.ClientCertificate));
}
}
Conventions
If you package that into an [AutoData] attribute, you should be able to refactor your test to:
[Theory, BasicConventions]
public void GetVersionOnSiteVersionControllerReturnsASiteVersion(
SiteVersionController sut,
SiteVersion expected)
{
SiteVersion actual = null;
var response = sut
.GetSiteVersion()
.ExecuteAsync(new CancellationToken())
.Result
.TryGetContentValue<SiteVersion>(out actual);
actual.AsSource().OfLikeness<SiteVersion>().ShouldEqual(expected);
}
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.
Currently in code i have used an object factory to return me a processor based of a string tag, which has severed its purpose up until now.
using Core;
using Data;
public static class TagProcessorFactory
{
public static ITagProcessor GetProcessor(string tag)
{
switch (tag)
{
case "gps0":
return new GpsTagProcessor();
case "analog_manager":
return new AnalogManagerTagProcessor();
case "input_manager":
return new InputManagerTagProcessor();
case "j1939":
return new J1939TagProcessor(new MemcachedProvider(new[] { "localhost" }, "DigiGateway"), new PgnRepository());
default:
return new UnknownTagProcessor();
}
}
}
Calling Code
var processor = TagProcessorFactory.GetProcessor(tag.Name);
if (!(processor is UnknownTagProcessor))
{
var data = processor.Process(unitId, tag.Values);
Trace.WriteLine("Tag <{0}> processed. # of IO Items => {1}".FormatWith(tag.Name, data.Count()));
}
as you can see one of my items has dependencies and im trying to execute testing code and i want to pass in mock repositories and cache providers but i can seem to think of a way to do this.
Is this a bad design or anyone have any ideas to fix it to make my factory testable?
Thanks
Since you are using Autofac, you can take advantage of the lookup relationship type:
public class Foo
{
private readonly IIndex<string, ITagProcessor> _tagProcessorIndex;
public Foo(IIndex<string, ITagProvider> tagProcessorIndex)
{
_tagProcessorIndex = tagProcessorIndex;
}
public void Process(int unitId, Tag tag)
{
ITagProcessor processor;
if(_tagProcessorIndex.TryGetValue(tag.Name, out processor))
{
var data = processor.Process(unitId, tag.Values);
Trace.WriteLine("Tag <{0}> processed. # of IO Items => {1}".FormatWith(tag.Name, data.Count()));
}
}
}
See the TypedNamedAndKeysServices wiki article for more information. To register the various processors, you would associate each with its key:
builder.RegisterType<GpsTagProcessor>().Keyed<ITagProcessor>("gps0");
builder.RegisterType<AnalogManagerTagProcessor>().Keyed<ITagProcessor>("analog_manager");
builder.RegisterType<InputManagerTagProcessor>().Keyed<ITagProcessor>("input_manager");
builder
.Register(c => new J1939TagProcessor(new MemcachedProvider(new[] { "localhost" }, new PgnRepository()))
.Keyed<ITagProcessor>("j1939");
Notice we don't register UnknownTagProcessor. That was a signal to the caller of the factory that no processor was found for the tag, which we express using TryGetValue instead.
Using something like StructureMap you could use the ObjectFactory which, when configured would return you a named concrete instance.
http://structuremap.net/structuremap/index.html
I suggest you look through another SO post. It solves several problems at once, including how to replace contructor values - without a mess. Specifically, the parameters to the constructor simply become static fields of a "Context" class, which are read by the constructor of the interior class.