I'm currently having a model class which contains several properties. A simplified model could look like this:
public class SomeClass
{
public DateTime ValidFrom { get; set; }
public DateTime ExpirationDate { get; set; }
}
Now I'm implementing some unit tests by using NUnit and use AutoFixture to create some random data:
[Test]
public void SomeTest()
{
var fixture = new Fixture();
var someRandom = fixture.Create<SomeClass>();
}
This works perfect so far. But there is the requirement that the date of ValidFrom is always before ExpirationDate. I have to ensure this since I'm implementing some positive tests.
So is there an easy way to implement this by using AutoFixture? I know I could create a fix date and add a random date interval to solve this, but it would be great if AutoFixture could handle this requirement itself.
I haven't got a lot of experience with AutoFixture, but I know I can get an ICustomizationComposer by calling the Build method:
var fixture = new Fixture();
var someRandom = fixture.Build<SomeClass>()
.With(some => /*some magic like some.ValidFrom < some.ExpirationDate here...*/ )
.Create();
Maybe this is the right way to achieve this?
Thanks in advance for any help.
It may be tempting to ask the question of how do I make AutoFixture adapt to my design?, but often, a more interesting question could be: how do I make my design more robust?
You can keep the design and 'fix' AutoFixture, but I don't think it's a particularly good idea.
Before I tell you how to do that, depending on your requirements, perhaps all you need to do is the following.
Explicit assignment
Why not simply assign a valid value to ExpirationDate, like this?
var sc = fixture.Create<SomeClass>();
sc.ExpirationDate = sc.ValidFrom + fixture.Create<TimeSpan>();
// Perform test here...
If you're using AutoFixture.Xunit, it can be even simpler:
[Theory, AutoData]
public void ExplicitPostCreationFix_xunit(
SomeClass sc,
TimeSpan duration)
{
sc.ExpirationDate = sc.ValidFrom + duration;
// Perform test here...
}
This is fairly robust, because even though AutoFixture (IIRC) creates random TimeSpan values, they'll stay in the positive range unless you've done something to your fixture to change its behaviour.
This approach would be the simplest way to address your question if you need to test SomeClass itself. On the other hand, it's not very practical if you need SomeClass as input values in myriads of other tests.
In such cases, it can be tempting to fix AutoFixture, which is also possible:
Changing AutoFixture's behaviour
Now that you've seen how to address the problem as a one-off solution, you can tell AutoFixture about it as a general change of the way SomeClass is generated:
fixture.Customize<SomeClass>(c => c
.Without(x => x.ValidFrom)
.Without(x => x.ExpirationDate)
.Do(x =>
{
x.ValidFrom = fixture.Create<DateTime>();
x.ExpirationDate =
x.ValidFrom + fixture.Create<TimeSpan>();
}));
// All sorts of other things can happen in between, and the
// statements above and below can happen in separate classes, as
// long as the fixture instance is the same...
var sc = fixture.Create<SomeClass>();
You can also package the above call to Customize in an ICustomization implementation, for further reuse. This would also enable you to use a customized Fixture instance with AutoFixture.Xunit.
Change the design of the SUT
While the above solutions describe how to change the behaviour of AutoFixture, AutoFixture was originally written as a TDD tool, and the main point of TDD is to provided feedback about the System Under Test (SUT). AutoFixture tends to amplify that sort of feedback, which is also the case here.
Consider the design of SomeClass. Nothing prevents a client from doing something like this:
var sc = new SomeClass
{
ValidFrom = new DateTime(2015, 2, 20),
ExpirationDate = new DateTime(1900, 1, 1)
};
This compiles and runs without errors, but is probably not what you want. Thus, AutoFixture is actually not doing anything wrong; SomeClass isn't properly protecting its invariants.
This is a common design mistake, where developers tend to put too much trust into the semantic information of the members' names. The thinking seems to be that no-one in their right mind would set ExpirationDate to a value before ValidFrom! The problem with that sort of argument is that it assumes that all developers will always be assigning these values in pairs.
However, clients may also get a SomeClass instance passed to them, and want to update one of the values, e.g.:
sc.ExpirationDate = new DateTime(2015, 1, 31);
Is this valid? How can you tell?
The client could look at sc.ValidFrom, but why should it? The whole purpose of encapsulation is to relieve clients of such burdens.
Instead, you should consider changing the design SomeClass. The smallest design change I can think of is something like this:
public class SomeClass
{
public DateTime ValidFrom { get; set; }
public TimeSpan Duration { get; set; }
public DateTime ExpirationDate
{
get { return this.ValidFrom + this.Duration; }
}
}
This turns ExpirationDate into a read-only, calculated property. With this change, AutoFixture just works out of the box:
var sc = fixture.Create<SomeClass>();
// Perform test here...
You can also use it with AutoFixture.Xunit:
[Theory, AutoData]
public void ItJustWorksWithAutoFixture_xunit(SomeClass sc)
{
// Perform test here...
}
This is still a little brittle, because although by default, AutoFixture creates positive TimeSpan values, it's possible to change that behaviour as well.
Furthermore, the design actually allows clients to assign negative TimeSpan values to the Duration property:
sc.Duration = TimeSpan.FromHours(-1);
Whether or not this should be allowed is up to the Domain Model. Once you begin to consider this possibility, it may actually turn out that defining time periods that move backwards in time is valid in the domain...
Design according to Postel's Law
If the problem domain is one where going back in time isn't allowed, you could consider adding a Guard Clause to the Duration property, rejecting negative time spans.
However, personally, I often find that I arrive at a better API design when I take Postel's Law seriously. In this case, why not change the design so that SomeClass always uses the absolute TimeSpan instead of the signed TimeSpan?
In that case, I'd prefer an immutable object that doesn't enforce the roles of two DateTime instances until it knows their values:
public class SomeClass
{
private readonly DateTime validFrom;
private readonly DateTime expirationDate;
public SomeClass(DateTime x, DateTime y)
{
if (x < y)
{
this.validFrom = x;
this.expirationDate = y;
}
else
{
this.validFrom = y;
this.expirationDate = x;
}
}
public DateTime ValidFrom
{
get { return this.validFrom; }
}
public DateTime ExpirationDate
{
get { return this.expirationDate; }
}
}
Like the previous redesign, this just works out of the box with AutoFixture:
var sc = fixture.Create<SomeClass>();
// Perform test here...
The situation is the same with AutoFixture.Xunit, but now no clients can misconfigure it.
Whether or not you find such a design appropriate is up to you, but I hope at least it's food for thought.
This is a kind of "extended comment" in reference to Mark's answer, trying to build on his Postel's Law solution. The parameter swapping in the constructor felt uneasy for me, so I've made the date swapping behaviour explicit in a Period class.
Using C#6 syntax for brevity:
public class Period
{
public DateTime Start { get; }
public DateTime End { get; }
public Period(DateTime start, DateTime end)
{
if (start > end) throw new ArgumentException("start should be before end");
Start = start;
End = end;
}
public static Period CreateSpanningDates(DateTime x, DateTime y, params DateTime[] others)
{
var all = others.Concat(new[] { x, y });
var start = all.Min();
var end = all.Max();
return new Duration(start, end);
}
}
public class SomeClass
{
public DateTime ValidFrom { get; }
public DateTime ExpirationDate { get; }
public SomeClass(Period period)
{
ValidFrom = period.Start;
ExpirationDate = period.End;
}
}
You would then need to customize your fixture for Period to use the static constructor:
fixture.Customize<Period>(f =>
f.FromFactory<DateTime, DateTime>((x, y) => Period.CreateSpanningDates(x, y)));
I think the main benefit of this solution is that it extracts the time-ordering requirement into its own class (SRP) and leaves your business logic to be expressed in terms of an already-agreed contract, apparent from the constructor signature.
Since SomeClass is mutable, here's one way of doing it:
[Fact]
public void UsingGeneratorOfDateTime()
{
var fixture = new Fixture();
var generator = fixture.Create<Generator<DateTime>>();
var sut = fixture.Create<SomeClass>();
var seed = fixture.Create<int>();
sut.ExpirationDate =
generator.First().AddYears(seed);
sut.ValidFrom =
generator.TakeWhile(dt => dt < sut.ExpirationDate).First();
Assert.True(sut.ValidFrom < sut.ExpirationDate);
}
FWIW, using AutoFixture with xUnit.net data theories, the above test can be written as:
[Theory, AutoData]
public void UsingGeneratorOfDateTimeDeclaratively(
Generator<DateTime> generator,
SomeClass sut,
int seed)
{
sut.ExpirationDate =
generator.First().AddYears(seed);
sut.ValidFrom =
generator.TakeWhile(dt => dt < sut.ExpirationDate).First();
Assert.True(sut.ValidFrom < sut.ExpirationDate);
}
Related
I have an application that will run once every minute. After completing, the app will write to a log table before it exits. This object closely maps that log table:
class SendResult
{
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public TimeSpan ExecutionTime { get
{
return EndTime - StartTime;
}
public bool RequestChecked{ get; set; }
public int RequestID { get; set; }
public bool RequestRequiresFileSend { get; set; }
public bool FilesRead { get; set; }
public bool FilesSent { get; set; }
public SendResult() { }
}
Each property will be updated at a different point in the app. I have achieved this by declaring the object once and making it static:
class Program
{
public static SendResult Result;
public Program()
{
Result = new SendResult();
Result.StartTime = DateTime.Now;
// do stuff...
Result.EndTime = DateTime.Now;
LogUtility.Log(Result);
}
}
..and everywhere throughout the app I just call:
Program.Result.FilesRead = ...
I know an alternative is to construct the app around SendResult, like this:
SendResult result = new SendResult();
result.StartTime = DateTime.Now;
var request = new RequestHandler().CheckRequest();
result.RequestChecked = request.Checked;
result.RequestID = request.RequestID;
result.RequestRequiresFileSend = request.FileSendRequired;
var sendResult = new FileSender(request.ResuestID).Send();
result.FilesRead = sendResult.FilesRead;
// ...and so on
But in a case where you have to insert this result tracking after all your code has been written, is there a better way than the global var method I have used?
The parts of the code summarized as "do stuff" should take in the SendResult instance as a dependency that is either explicitly pushed into them, or possibly resolved in some way other than directly depending on accessing a static field in Program. You can pass the reference directly using constructor arguments, object properties, or method parameters. Indirect ways to do that could be implemented using an IoC/DI container. The idea is to reduce coupling, which is most of the time a good idea.
Potentially, your application could benefit from using the Pipes and Filters Architectural Pattern, but only if you have scaleability and flexibility requirements. Otherwise, the introduced complexities would be counterproductive for your particular case.
Static variables are usually not a good idea, there is almost no uses of them in the modern application with Dependency Injection. It's use adds a state and increase coupling, making it much more complicated to e.g. unit test all your components in isolation.
So the simplest approach would be to just create the required object and send it to all the methods that require editing. It's a bit hard to say generally though, it might be better that all your methods do return their own objects that are later composed into the resulting one that is saved to the database.
But while there can be different strategies to achieve what you want, using static variable is most likely not the best of them.
A project I'm working on would benefit from having a little more abstraction added to it and I'm faced with a problem I can't seem to get past.
Essentially is we have services that can be assigned and consumed, but the rates at which they are consumed are all a little different. This distinction is important for reporting and for scheduling the consumption of these services.
I'm not really sure how to take data I receive from the database and ensure that the correct concrete type is created. Am I overthinking this and there is something easier I can do? The only thing I can think of doing is having a switch statement determine which type to make based on the unit of time specified, but that seems sloppy.
UnitInterval (which I'm welcome to renaming it something that seems less confusing), is supposed to hold the service's consumption unit (1, 15, 30, 60) and then the UnitSize will be minutes, hours, or days. The UnitSizes are held in a reference table and ID'ed with their appropriate text of Day, Minute, Hour. So in my table Minute has an ID = 1, Hour = 2, Day = 3, and depending on if these intervals need to be adjusted they can be in the future.
How do I get something like the UnitSize from the database and ensure the correct implementation? Am I just going about this the entirely wrong way?
Essentially my end game is that I'll have another class which just contains List<WorkableService> that I can use to spit out a report with the correct units, any costing, duration, etc.
public abstract class WorkableService
{
public int UnitSizeId { get; set; }
public string UnitSizeText { get; set; }
public double UnitInterval { get; set; }
public abstract TimeSpan Duration { get; }
public double UnitsAvailable { get; set; }
public double Adjustment { get; set; }
public decimal Rate { get; set; }
}
public class MinuteService : WorkableService
{
public override TimeSpan Duration
{
get
{
return TimeSpan.FromMinutes(UnitInterval);
}
}
}
public class HourlyService : WorkableService
{
public override TimeSpan Duration
{
get
{
return TimeSpan.FromHours(UnitInterval);
}
}
}
public class DailyService : WorkableService
{
public override TimeSpan Duration
{
get
{
return TimeSpan.FromDays(UnitInterval);
}
}
}
The switch method is totally valid, if you know for sure at compile time all the options you might need. More basic info at the Wikipedia factory pattern, but switching on an enum value or a string identifier is the general concept.
Alternatively, look into Activator.CreateInstance, which you can use to create a new object based on the type's name that you might dynamically load from the database. We do that in some situations to let us add new supported types without recompiling the base service.
The switch statement you refer to as sloppy is something called the Factory pattern. Assuming your WorkableService base constructor takes UnitInterval:
static class WorkableServiceFactory
{
public static WorkableService Get(int unitSizeId, double unitInterval)
{
switch (unitSizeId)
{
case 1:
return new MinuteService(unitInterval);
case 2:
return new HourlyService(unitInterval);
case 3:
return new DailyService(unitInterval);
default:
throw new ArgumentOutOfRangeException("unitSizeId");
}
}
}
I'm usually not a fan of factories (they're the butt of every Java EE joke in the book for a reason), but this is actually a valid scenario for it.
I have an object that takes plenty of parameters to its constructor (from 9 to 13 depending on use).
I want to avoid the ugliness of new MyObject(param1, param2, param3 ... param13).
My first attempt was to create a class MyObjectParams with properties with public getters and setters, it gives something like that :
var objectParams = new MyObjectParams
{
Param1 = ...,
Param2 = ...,
...
};
I see some big projects like SlimDX for their PresentParameters use this design. It looks better. But the class is not immutable.
I'd like my MyObjectParams to be immutable while still using a clean construction style. This is how it would look like with an immutable class :
var objectParams = new MyObjectParams
(
param1,
param2,
...
);
Note: it's just the long constructor line broken into several, so it's cleaner but still not as readable as initializers.
I was thinking of using named parameters to get both an immutable class and a more or less clean code, but I'm not sure whether this actually is a good idea:
var objectParams = new MyObjectParams
(
param1: ...,
param2: ...,
...
);
Should I use named parameters? Can you think of a better approach to solve this problem?
Edited regarding an answer below: unfortunately, I don't really think the design is bad. The 9 parameters really are required and remain constant throughout the entire life of the object. I cannot provide a default value for them as it is completely usage-dependant.
Have you looked into designing a solution in which you wouldn't need this amount of parameters? Having a lot of parameters makes the code very tightly coupled which reduces maintainability. Maybe you can redesign a small amount of code to a design which better separates the responsibilities of the class?
I really like the way The Zen of Python says a few things:
Simple is better than complex.
Complex is better than complicated.
[...]
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
I believe that having a dedicated Options class of some kind with the exhaustive list of all possible parameters is a good idea. Allow your MyObject constructor to require an Options instance, and then store a reference to the instance as a field on MyObject and refer to its getters/setters. (Storing the reference will be much superior to trying to parse the options and transfer their values to the MyObject instance. Now that would be messy.) With all data access delegated to the Options class, you will have successfully encapsulated the object's configuration, and you've designed a simple API for option access as the same time.
If Options has no reason to be publicly accessible, make it a private class definition and then you're free to maintain changes to Options logic without modifying MyObject. I believe that is a fair solution to you as the developer, and doesn't commit atrocities.
The constructor could have only a small number of parameters, the ones required for proper object initialization. You could then have a number of properties that can be set after the object has been constructed. You can set default values for those properties in the constructor and the client can set the ones he/she requires.
class Person
{
public Person(string name, int age)
{
Name = name;
Age = age;
Address = "Unknown";
Email = "Unknown";
}
public string Name {get; private set;}
public int Age {get; private set;}
public string Email {get; set;}
public string Address {get; set;}
}
Person p = new Person("John Doe", 30);
p.Email = "john.doe#example.org";
You could use the builder pattern to construct an immutable object.
public sealed class ComplexObject
{
public int PropA { get; private set; }
public string PropB { get; private set; }
public sealed class Builder
{
int _propA;
string _propB;
public Builder SetPropA(int propA)
{
// validate
_propA = propA;
return this;
}
public Builder SetPropB(string propB)
{
// validate
_propB = propB;
return this;
}
public CustomObject ToCustomObject()
{
return new CustomObject
{
PropA = _propA,
PropB = _propB
};
}
}
}
Usage
var custom =
new CustomObject.Builder()
.SetPropA(1)
.SetPropB("Test")
.ToCustomObject();
Final Thoughts
Despite my previous suggestion I am in no way against using named parameters if they are available.
I'm attempting to implement a 'Requirements' type system into a program. It seemed pretty simple in my head, but actually making it abstract enough to be useful is proving more difficult than anticipated.
Here is what I am trying to do ...
enum Condition {
Not, Exists, Exceeds
}
abstract class Requirement {
// base class
Condition Condition { get; set; }
}
class ScoreRequirement : Requirement {
// a specific 'score' is required
}
class TraitRequirement : Requirement {
// a specific 'trait' is required
}
class SatisfyingObject {
// this is the class that has to satisfy the requirements
IDictionary<Trait, int> Traits { get; set; }
}
If I know the exact thing that has to be satisfied in code-time, this is very simple. But the goal is to let people add requirements later. There will be other types that derive from Requirement, as well.
So a requirement might work like this ...
var obj = new Item {
Requirements = new List<Requirement> {
new ScoreRequirement { Trait = "One", Score = 2, Condition = Condition.Exceeds }
}
}
So the concept seems pretty simple. You would call upon an object..
var satisfying = // get the satisfying object;
if( satisfying.Satisfies( obj.Requirements ) )
return true;
The problem I am running into is really how to code the Satisfies method - in specific I am not sure how to relate it to the Condition parameter. I'd like people to be able to set up some fairly generic 'requirements', but the logic behind this is very confusing to me. Since the requirements are not known at design time, I cannot really hard code any of them.
Any suggestions?
If this isn't a learning project than I would highly recommend you look at using something that is already built for this:
EntLib Validation Block
Fluent Validation
Anything built on top of the System.ComponentModel.DataAnnotations
If however you are doing this as a simple learning project, than you have 2 basic approaches you could take:
Reflection based
Delegate based
Of the two, delegate based is going to be much simpler to implement, but less flexible. I have implemented this pattern several times and the concept is simple. Here is about the most basic concept you can get.
public interface IRuleDefinition
{
String PropertyName { get; }
String Message { get; }
}
public class ValidationRule<T>: IRuleDefinition
{
public String PropertyName { get; private set; }
public String Message { get; private set; }
private Func<T, Boolean> _isValidDelegate;
public ValidationRule(Func<T, Boolean> isValidDelegate, String propertyName, String message)
{
PropertyName = propertyName;
Message = message;
_isValidDelegate = isValidDelegate;
}
public Boolean IsValid(T objToValidate)
{
return _isValidDelegate(objToValidate);
}
}
public class Validator<T>
{
private List<ValidationRule<T>> _validationRules = new List<ValidationRule<T>>();
public void AddRule(Func<T, Boolean> isValidDelegate, String propertyName = null, String message = null)
{
_validationRules.Add(new ValidationRule<T>(isValidDelegate, propertyName, message));
}
public Boolean IsValid(T objToValidate)
{
return _validationRules.Any(vr => vr.IsValid(objToValidate));
}
public IEnumerable<IRuleDefinition> GetViolations(T objToValidate)
{
return _validationRules
.Where(vr => !vr.IsValid(objToValidate))
.Cast<IRuleDefinition>();
}
}
You can use it in code like this:
var myObj = new MyObject{ Name = "Josh", Age = 29 };
var myObjValidator = new Validator<MyObject>();
myObjValidator.AddRule(
obj => !String.IsNullOrWhitespace(obj.Name),
"Name", "Name is required!");
myObjValidator.AddRule(
obj => obj.Age < 99,
"Age", "Age must be less than 99");
myObjValidator.AddRule(
obj => obj.Name == "Logan" && obj.Age < 29,
message: "RUN!!!");
if(!myObjValidator.IsValid(myObj))
{
foreach(var violation in myObjValidator.GetViolations(myObj))
Console.WriteLine("Property: {0}, Message: {1}",
violation.PropertyName, violation.Message);
}
Now, this was all from memory, so there may be some are probably coding/compiler errors in all this, but hopefully you get the general idea.
Again, if this isn't a learning project, then don't reinvent the wheel unless you are planning to learn more about wheels :)
I recommend determining the bare minimum scope required for specifying requirements and start with that, to see how complex the design becomes. If you're finding that even the minimum scope leads to a lot of complexity or if you can't even get a grasp on what the minimum scope would be, then you may want to look into a more flexible approach, like hosting a scripting language to be used for expressing your constraints. There are a wide range of available libraries to support this and they will be cheaper to support/maintain than something you've created and evolved yourself in an effort to provide an 'easy' way of setting constraints.
Keep it simple if you can, but if it really does need to be complicated, try to find something already built and tested as a foundation, so as to reduce the burden of the complexity.
When working with Domain Objects, how do you typically unit test a method that calls another method in the object? For example:
public class Invoice
{
public IList<InvoiceLine> InvoiceLines;
public string Company;
public bool IsDiscounted;
public DateTime InvoiceDate;
//...
public GetTotalAmt();
public GetExtendedTotalAmt();
public decimal GetTotalAmt()
{
decimal total;
foreach (InvoiceLine il in InvoiceLines)
{
total += il.Qty * il.Price;
}
return total;
}
public decimal GetExtendedTotalAmt()
{
decimal discount;
if (IsDiscounted)
discount = .05M;
return GetTotalAmt() * discount;
}
}
Unit testing GetTotalAmt() is easy, but with GetExtendedTotalAmt() I'd have to use stub/mock InvoiceLine objects to make it work, when all I really want to do is test that a discount is applied if the IsDiscounted flag is true.
How do other people handle this? I don't think it makes sense to split up the domain object since these methods are both considered part of the core Invoice functionality (and splitting it would likely cause developers to call the wrong method more often).
Thanks!
You could make the GetTotalAmt method virtual and then:
var sut = new MockRepository().PartialMock<Invoice>();
sut.Expect(x => x.GetTotalAmt()).Return(10);
sut.Replay();
var result = sut.GetExtendedTotalAmt();
I would build up a situation which is as simple as possible: only one InvoiceLine with a Quantity and Price of 1.
Something like this:
invoice.Add(new InvoiceLine(new Article("blah", 1M), 1));
Assert.AreEqual(0.95M, invoice.GetExtendedTotalAmt());
When you find that this stuff gets quite complicated, finding errors gets hard etc, then it is a sign that you should split the class (making the calculations on the invoice a strategy or something similar). But as long as it is as simple as you piece of code here, I wouldn't worry about it.