Fixture.Customize vs Fixture.Register - autofixture

Please explain the functional difference between Customize and Register, when to use one over the other. The TestCustomize example below fails and the TestRegister passes. I expected the customize script to work fine. It reads to me in English as:
"When generating an HttpClient, use a post-processing lambda on it before providing the specimen".
But what I get is an HTTP address with a GUID in it, clearly generated by AutoFixture.
[Fact]
public void TestCustomize()
{
var fixture = new Fixture();
fixture.Customize<HttpClient>(c =>
{
//c.OmitAutoProperties(); makes no difference
c.Do(x => x.BaseAddress = new Uri("http://myval"));
return c;
});
var client = fixture.Create<HttpClient>();
Assert.Equal("http://myval/", client.BaseAddress.ToString());
}
[Fact]
public void TestRegister()
{
var fixture = new Fixture();
fixture.Register(() => new HttpClient
{
BaseAddress = new Uri("http://myval")
});
var client = fixture.Create<HttpClient>();
Assert.Equal("http://myval/", client.BaseAddress.ToString());
}

This has nothing to do with Customize vs. Register. In fact, if you look at the source code for Register, you'll see that it's only a convenience method over Customize.
The problem lies in the use of Do. If you look at the signature of Do, you'll see that it has this type:
IPostprocessComposer<T> Do(Action<T> action)
Notice that the method returns a value. In Functional style, or, if you will, following Command-Query Separation, the method doesn't mutate the instance on which it's defined, but rather returns a new object with the changed behaviour.
When one writes:
c.Do(x => x.BaseAddress = new Uri("http://myval"));
one immediately discards the return value with the changed behaviour. In languages like F# or Haskell, you'd get a compile-time notification if you wrote code like that, telling you that you'd be ignoring the return value of a function call, but C# doesn't do that.
In any case, AutoFixture's APIs are designed as fluent interfaces. The intent is that you chain method calls together:
fixture.Customize<HttpClient>(c => c
.Without(x => x.BaseAddress)
.Do(x => x.BaseAddress = new Uri("http://myval")));
You still need Without (or, if you will, OmitAutoProperties) to turn off the default auto-property behaviour, because otherwise, BaseAddress will be overwritten by the auto-property feature.
This version of the test passes:
[Fact]
public void TestCustomize()
{
var fixture = new Fixture();
fixture.Customize<HttpClient>(c => c
.Without(x => x.BaseAddress)
.Do(x => x.BaseAddress = new Uri("http://myval")));
var client = fixture.Create<HttpClient>();
Assert.Equal("http://myval/", client.BaseAddress.ToString());
}

Related

How can I set the value of a protected var in a mock test (CakePHP)

I want to test a Shell that calls an API. The Shell has a function that sets the value for a protected var protected $_credential = [];
class ImportShell extends AppShell
{
protected $_credential = [];
public function sales() {
$credential = $this->Credential->find('first', [
'conditions' => [
'Credential.id' => $this->args[0]
]
]);
$this->_credential = $credential;
}
}
It uses the values in $this->args to find a Table entry and write that result into $_credential
How can I access/change $_credential in my test when I use it like this?
$ImportShell = $this->getMockBuilder('ImportShell')
->setMethods(array('find'))
->getMock();
$ImportShell->sales();
Also how can I access/change $this->args?
Use reflections
Reflections provide a mechanism to modify and interrogate code, and has a specific function to set a property value. The syntax is a little unwheildy but this allows you to modify the accessibility and value of class properties (and functions). Something like this would do what you want:
$class = new ReflectionClass("ImportShell");
$property = $class->getProperty("_credential");
$property->setAccessible(true);
$ImportShell = $this->getMockBuilder('ImportShell')
->setMethods(array('find'))
->getMock();
$ImportShell->_credential = ['stuff'];
There's a plugin for that
The Friends Of Cake Test Utilities plugin simplifies the syntax to achieve the same thing. The syntax using this plugin would be:
$this->setProtectedProperty('_credential', ['stuff'], $ImportShell);
Is it really necessary though?
args is a public property. Instead of manipulating a protected property, it is possible to simply set the public property that is used to populate it before calling the test function.
$ImportShell = $this->getMockBuilder('ImportShell')
->setMethods(array('find'))
->getMock();
$ImportShell->args = ['stuff'];
$ImportShell->sales();
Though given the way the question is phrased, it'd probably make more sense to mock the Credential model and add an expectation that it'll be called, and return what you want it to.

How can I customize a property's regex for AutoFixture?

I just changed my [RegularExpression] validation and a third of my unit tests broke!
It turns out AutoFixture is generating values based on that regex, which is cool, but it doesn't understand all regexs, so I'd like to supply it with a simpler one:
Fixtures.Customize<Details>(c => c.With(d => d.PhoneNumber,
new SpecimenContext(Fixtures).Resolve(
new RegularExpressionRequest(#"[2-9]\d{2}-\d{3}-\d{4}"))));
This ends up giving me a generic LINQ error ("Sequence contains no elements.") at object creation time. What am I doing wrong?
Alternatively, is there any way I can just turn this feature off? Customize() is helpful, but it prevents me from using Build() without repeating all the same logic. (Doesn't it?)
You can't easily turn that feature off, but you can easily override it:
public class Details
{
[RegularExpression(#"?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$")]
public string PhoneNumber { get; set; }
}
public class DetailsTests
{
[Fact]
public void OverridePhoneNumberRegularExpression()
{
var fixture = new Fixture();
var pattern = #"[2-9]\d{2}-\d{3}-\d{4}";
var phoneNumber =
new SpecimenContext(fixture).Resolve(
new RegularExpressionRequest(pattern));
fixture.Customize<Details>(c => c
.With(x => x.PhoneNumber, phoneNumber));
var sut = fixture.Create<Details>();
var actual = sut.PhoneNumber;
Assert.True(Regex.IsMatch(actual, pattern));
}
}
This test passes and looks similar to the one shown in the question. – What other members are defined in Details class?

New to AutoFixture trying to get my head around it and I can't see it helping me

Currently, I'm using custom made fake objects that behind the scenes use NSubstitute which creates the actual objects but it's becoming very hard to maintain as the project grows, so I'm trying to find alternatives and I'm hoping that AutoFixture is the right tool for the job.
I read the documentation and I'm struggling because there's very little to no documentation and I read most of the blog posts by Mark Seemann including the CheatSheet.
One of the things that I'm having hard time to grasp is how to create an object with a constructor that have parameters, in my case I need to pass argument to CsEmbeddedRazorViewEngine as well as HttpRequestBase to ControllerContext.
The way I see it is that I need to create a fake objects and finally create a customization object that injects them to
I also looked into NBuilder it seems slightly more trivial to pass arguments there but I've heard good things about AutoFixture and I would like to give it a try. :)
I'm trying to reduce the amount of fake objects I have so here is a real test, how can I do the same thing with AutoFixture?
[Theory,
InlineData("en-US"),
InlineData("en-us"),
InlineData("en")]
public void Should_return_the_default_path_of_the_view_for_enUS(string language)
{
// Arrange
const string EXPECTED_VIEW_PATH = "~/MyAssemblyName/Views/Home/Index.cshtml";
CsEmbeddedRazorViewEngine engine = CsEmbeddedRazorViewEngineFactory.Create(ASSEMBLY_NAME, VIEW_PATH, string.Empty);
string[] userLanguage = { language };
HttpRequestBase request = FakeHttpRequestFactory.Create(userLanguage);
ControllerContext controllerContext = FakeControllerContextFactory.Create(request);
// Act
ViewEngineResult result = engine.FindPartialView(controllerContext, VIEW_NAME, false);
// Assert
RazorView razorView = (RazorView)result.View;
string actualViewPath = razorView.ViewPath;
actualViewPath.Should().Be(EXPECTED_VIEW_PATH);
}
P.S. I'm using xUnit as my testing framework and NSubstitute as my mocking framework should I install both AutoFixture.Xunit and AutoFixture.AutoNSubstitute?
UPDATE: After learning more and more about it I guess it is not the right tool for the job because I tried to replace my test doubles factories with AutoFixture rather than setting up my SUT with it.
Due to odd reason I thought it's doing the same thing NBuilder is doing and from what I can see they are very different tools.
So after some thinking I think I'll go and change the methods I have on my test doubles factories to objects then use AutoFixture to create my SUT and inject my test doubles to it.
Note: I don't have the source code for the CsEmbeddedRazorViewEngine type and all the other custom types.
Here is how it could be written with AutoFixture:
[Theory]
[InlineAutoWebData("en-US", "about", "~/MyAssemblyName/Views/Home/Index.cshtml")]
[InlineAutoWebData("en-US", "other", "~/MyAssemblyName/Views/Home/Index.cshtml")]
public void Should_return_the_default_path_of_the_view_for_enUS(
string language,
string viewName,
string expected,
ControllerContext controllerContext,
CsEmbeddedRazorViewEngine sut)
{
var result = sut.FindPartialView(controllerContext, viewName, false);
var actual = ((RazorView)result.View).ViewPath;
actual.Should().Be(expected);
}
How it works:
It uses AutoFixture itself together with it's glue libraries for xUnit.net and NSubstitute:
PM> Install-Package AutoFixture.Xunit
PM> Install-Package AutoFixture.AutoNSubstitute
With InlineAutoWebData you actually combine inline values and auto-generated data values by AutoFixture – also including Auto-Mocking with NSubstitute.
internal class InlineAutoWebDataAttribute : CompositeDataAttribute
{
internal InlineAutoWebDataAttribute(params object[] values)
: base(
new InlineDataAttribute(values),
new CompositeDataAttribute(
new AutoDataAttribute(
new Fixture().Customize(
new WebModelCustomization()))))
{
}
}
Remarks:
You could actually replace the WebModelCustomization customization above with AutoNSubstituteCustomization and it could work.
However, assuming that you are using ASP.NET MVC 4, you need to customize the Fixture instance with:
internal class WebModelCustomization : CompositeCustomization
{
internal WebModelCustomization()
: base(
new MvcCustomization(),
new AutoNSubstituteCustomization())
{
}
private class MvcCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customize<ControllerContext>(c => c
.Without(x => x.DisplayMode));
// Customize the CsEmbeddedRazorViewEngine type here.
}
}
}
Further reading:
Encapsulating AutoFixture Customizations
AutoData Theories with AutoFixture
I ended up doing this.
[Theory,
InlineData("en-US", "Index", "~/MyAssemblyName/Views/Home/Index.cshtml"),
InlineData("en-us", "Index", "~/MyAssemblyName/Views/Home/Index.cshtml"),
InlineData("en", "Index", "~/MyAssemblyName/Views/Home/Index.cshtml")]
public void Should_return_the_default_path_of_the_view(string language, string viewName, string expected)
{
// Arrange
CsEmbeddedRazorViewEngine engine = new CsEmbeddedRazorViewEngineFixture();
ControllerContext controllerContext = FakeControllerContextBuilder.WithLanguage(language).Build();
// Act
ViewEngineResult result = engine.FindPartialView(controllerContext, viewName, false);
// Assert
string actualViewPath = ((RazorView)result.View).ViewPath;
actualViewPath.Should().Be(expected);
}
I encapsulated the details to setup my SUT into a fixture and used the builder pattern to handle my fakes, I think that it's readable and pretty straightforward now.
While AutoFixture looks pretty cool, the learning curve seems long and I will need to invest enough time to understand it, for now, I want to clean-up my unit tests and make them more readable. :)

EF ObjectQuery<T> Context, Parameters, Connection properties equivalent on DbSet<T>

In the earlier versions of Entity Framework, we were able to reach the Context out of ObjectQuery in order to read Parameters, Connection, etc. as below:
var query = (ObjectQuery<T>)source;
cmd.Connection = (SqlConnection)((EntityConnection)query.Context.Connection).StoreConnection;
cmd.Parameters.AddRange(
query.Parameters.Select(x => new SqlParameter(
x.Name, x.Value ?? DBNull.Value)
).ToArray()
);
When I look at the DbSet<T> object, I am unable to find any equivalent of this. My purpose here is to create extensions which will manipulate the query and get the result out of it.
Here is an instance: http://philsversion.com/2011/09/07/async-entity-framework-queries
Or should I write the extension for DbContext class and work with Set method?
Any idea?
Edit
Here is what I did so far. Basic implementation so far but certainly not ready for production. Any suggestions on this?
public static async Task<IEnumerable<T>> QueryAsync<T>(this DbContext #this, System.Linq.Expressions.Expression<Func<T, bool>> predicate = null)
where T : class {
var query = (predicate != null) ? #this.Set<T>().Where(predicate) : #this.Set<T>();
var cmd = new SqlCommand();
cmd.Connection = (SqlConnection)(#this.Database.Connection);
cmd.CommandText = query.ToString();
if (cmd.Connection.State == System.Data.ConnectionState.Closed) {
cmd.Connection.ConnectionString = new SqlConnectionStringBuilder(cmd.Connection.ConnectionString) {
AsynchronousProcessing = true
}.ToString();
cmd.Connection.Open();
}
cmd.Disposed += (o, e) => {
cmd.Clone();
};
var source = ((IObjectContextAdapter)#this).ObjectContext.Translate<T>(
await cmd.ExecuteReaderAsync()
);
return source;
}
This is a nice workaround, although I don't think you can make it much more generally applicable than what you already have.
A few things to keep in mind:
- Depending on the EF query, e.g. if you are using Include or not, the columns returned in the reader might not match the properties in the type T you are passsing.
- Depending on whether you have inheritance in your model, the T that you pass to translate may not always be the right thing to materialize for every row returned.
- After the task returned by ExecuteReaderAsync completes, you still have to retrieve each row, which depending on the execution plan for the query and the latency you are getting with the server is potentially also a blocking operation.
Async support is not coming to EF in 5.0 but we worked with other teams to make sure we have all the necessary building blocks included in .NET 4.5 and the feature is pretty high in our priority list. I encourage you to vote for it in our UserVoice site.

How to achieve "Blendability" when using DataServiceCollection in my ViewModel

I'm looking at using oData endpoints in my Silverlight client. Naturally, I'm doing MVVM and I want the project to be nice and "Blendable" (i.e. I must be able to cleanly use static data instead of the oData endpoints when in design mode.)
Now to the problem. I'd like to use the DataServiceCollection in my ViewModels, since it allows for nice bindable collections without having to worry too much with BeginExecute/EndExecute etc.
Now, let's look at some code. My Model interface looks like this:
public interface ITasksModel
{
IQueryable<Task> Tasks { get; }
}
The oData endpoint implementation of that interface:
public class TasksModel : ITasksModel
{
Uri svcUri = new Uri("http://localhost:2404/Services/TasksDataService.svc");
TaskModelContainer _container;
public TasksModel()
{
_container = new TaskModelContainer(svcUri);
}
public IQueryable<Task> Tasks
{
get
{
return _container.TaskSet;
}
}
}
And the "Blendable" design-time implementation:
public class DesignModeTasksModel : ITasksModel
{
private List<Task> _taskCollection = new List<Task>();
public DesignModeTasksModel()
{
_taskCollection.Add(new Task() { Id = 1, Title = "Task 1" });
_taskCollection.Add(new Task() { Id = 2, Title = "Task 2" });
_taskCollection.Add(new Task() { Id = 3, Title = "Task 3" });
}
public IQueryable<Task> Tasks
{
get {
return _taskCollection.AsQueryable();
}
}
}
However, when I try to use this last one in my ViewModel constructor:
public TaskListViewModel(ITasksModel tasksModel)
{
_tasksModel = tasksModel;
_tasks = new DataServiceCollection<Task>();
_tasks.LoadAsync(_tasksModel.Tasks);
}
I get an exception:
Only a typed DataServiceQuery object can be supplied when calling the LoadAsync method on DataServiceCollection.
First of all, if this is the case, why not make the input parameter of LoadAsync be typed as DataServiceQuery?
Second, what is the "proper" way of doing what I'm trying to accomplish?
The reason LoadAsync requires DataServiceQuery is that just plain IQueryable doesn't define asynchronous way of executing the query. The reason the method takes IQueryable type as its parameter is so that users don't have to cast the query object to DataServiceQuery explicitely (makes the code shorter) and since we assume that users will try to run their code at least once, they would see the error immediately (as you did).
LoadAsync only supports asynchronous operations, so it needs the DataServiceQuery. If you already have the results (without a need to execute async request) you can call the Load method instead. Which is the answer to your second question. Instead of calling LoadAsync for both desing time and run time, you could use Load for design time and LoadAsync for run time. But due to tracking constrains you might need to create the DataServiceCollection in different way.
Something like this:
DataServiceCollection<Task> dsc;
DataServiceQuery<Task> dsq = _tasksModel as DataServiceQuery<Task>;
if (dsq != null)
{
dsc = new DataServiceCollection<Task>();
dsc.LoadAsync(dsq);
}
else
{
dsc = new DataServiceCollection<Task>(myDataServiceContext);
dsc.Load(_tasksModel);
// Invoke the LoadAsyncCompleted handler here
}
If you pass the DataServiceContext to the constructor before caling Load the entities will be tracked (just like in the LoadAsync case). If you don't need that you can call the constructor which takes IEnumerable and TrackingMode and turn off tracking on it.

Resources