Automate the testing of property assignments in constructor - c#

In my domain layer I create a lot of classes which looks like this
public class Route
{
public Route(Location origin, Location destination)
{
this.Origin = origin;
this.Destination = destination;
}
public Location Origin { get; }
public Location Destination { get; }
}
Now I need to unit-test this constructor
[Test]
public void PropertiesAreAssigned()
{
var origin = new Location(...);
var destination = new Location(...);
var route = new Route(origin, destination);
route.Origin.Should().Be(origin);
route.Destination.Should().Be(destination);
}
I have quite a few of those classes and tests which are very similar to each other. What I'd like is to have some kind of method which just accepts the type arguments, and then does all the testing for me, i.e.
instantiate a variable per constructor parameter (with whole graph of dependencies needed)
pass these variables to constructor
checks that the property values are assigned correctly
I'm pretty sure I can do this with a bit of reflection, but maybe is there an existing library for doing that? More tests are welcome, e.g.
Testing the null argument throws the proper exception
Testing that Equals and GetHashCode are implemented correctly

For me testing a simple constructor, simple accessors and mutators are a bad practice... It will be covered with behavioral (with intention) test. The less you test implementation details, the more your tests will be robust and resist to changes.
Testing constructor with complex behavior can be useful. But I often try to don't have any complex behavior in my constructors ^^

Related

AutoFixture - Creation of "Valid" and "Invalid" instances and [AutoData]

I created following sample model:
internal sealed class Bike : IVehicle
{
public Bike(
Engine engineType,
WindowHue windowHue,
Vehicle transport,
ushort wheelsCount,
string name) =>
(EngineType, WindowHue, Transport, WheelsCount, Name) =
(engineType, windowHue, transport, wheelsCount, name);
public WindowHue WindowHue { get; }
public Engine EngineType { get; }
public Vehicle Transport { get; }
public ushort WheelsCount { get; }
public string Name { get; }
}
I'm currently writing unit tests for Bike validator and I would like to use AutoFixture to create instances of Bike class that have values that are considered valid and invalid. Is there a way to instruct AutoFixture how to create those types of instances and tell it to fetch valid or invalid one depending on unit test that is running? For example: in test case that checks whether valid instance of Bike class passes validation I would like AutoFixture to create a valid Bike instance.
I attempted to achieve this behavior by creation of custom specimen builders but it seems that the last one that is registered is used to create an actual instance of requested type. Other idea was to create builder class that would use AutoFixture to create valid and invalid instances [via "Create" method] and use it in test cases, but I think that is not a good idea, since it leads to creation of redundant code [builder class per tested model].
If above behavior is possible, then is there a way to create such instances by using [AutoData] attribute, so that I don't have to call AutoFixture in test case body?
Yes you can, however the complexity of your setup code will depend on the complexity of your domain.
You could declare a customization that would build your DTO models with valid data, then use it via a custom [AutoData] attribute, and inside the test customize some of the DTOs with invalid data using .Customize<T>() or .Build<T>().
Now if you want to provide your invalid DTOs from the test parameters you could try to implement a [Invalid] attribute, that would customize individual test parameters, then use [Frozen] to use the value in other generated models.
For the [Invalid] attribute you can implement either the CustomizeAttribute from the AutoFixture.NUnit3 package or the IParameterCustomizationSource from AutoFixture.
As you'll see the output of the customization attribute is an ICustomization meaning inside the attribute you'll likely have a dictionary that outputs a customization for an invalid entity depending on the parameter type.
NB: I would really advise you use the first approach since it makes it obvious in what way the input data is invalid and makes asserting the results easier.
I would probably leave automapper out of this and create a class that takes care of creating the different types (invalid or valid) of objects that tests need:
Enums.cs
public enum BikeType
{
Valid,
Invalid
}
BikeCreator.cs
public static class BikeCreator
{
private Bike CreateValidBike()
{
return new Bike() //make this object "valid"
}
private Bike CreateInvalidBike()
{
return new Bike(); //make this object "invalid"
}
public Bike CreateInstance(BikeType bikeType)
{
Bike bike = null;
switch (bikeType)
{
case BikeType.Valid:
user = CreateValidBike();
break;
case BikeType.Invalid:
user = CreateInvalidBike();
break;
};
return bike;
}
}
That allows me to call that class in the following way:
//arrange
var invalidBike = BikeCreator.CreateInstance(BikeType.Invalid);
var validBike = BikeCreator.CreateInstance(BikeType.Valid);
This could be a good boilerplate to refactor into something more fancy with interfaces and generics. Sometimes "premature optimization is the root of all evil"

Moq setup returns reference to object

Let's say I have a simple class called MyRequestHandler, and it has a method called ProcessRequest that simply takes a request object, maps it to a return object and returns that object. (This is obviously a very simple example of a much more complex method/test that I'm working on).
public class MyRequestHandler
{
private IMapper _mapper;
public MyRequestHandler(IMapper maper)
{
_mapper = mapper;
}
public MyReturnObject ProcessRequest(MyRequestObject requestObject)
{
MyReturnObject returnObject = _mapper.Map<MyReturnObject>(requestObject);
return returnObject;
}
}
Now for unit testing (using Xunit), I want to test the ProcessRequest method, but obviously want to Moq the Map method, as such:
MyRequestObject requestObject = new RequestObject()
{
RequestInt = 1,
RequestString = "Hello"
};
MyReturnObject returnObject = new MyReturnObject()
{
MyInt = 1,
MyString = "Hello"
};
Mock<IMapper> mockMapper = new Mock<IMapper>();
mockMapper.Setup(m => m.Map<MyRequestObject>(requestObject)).Returns(returnObject);
MyRequestHandler requestHandler = new MyRequestHandler(mockMapper.Object);
MyReturnObject response = requestHandler.ProcessRequest(requestObject);
Assert.Equal(returnObject.MyInt, response.MyInt);
Assert.Equal(returnObject.MyString, response.MyString);
The problem here is that Moq returns (and I guess it should be obvious that it is) a reference to returnObject, so my Asserts will always pass, even if my method were to change a value prior to returning the object. Now I could instantiate a new MyReturnObject in the Moq Setup/Return and compare the MyInt and MyString by the values I give to the new one, but what if it's a really complex object with 20 properties and lists of objects? Maybe I want to use AutoFixture to create the object being returned and use DeepEqual to compare them? Is this even possible? Am I looking at this wrong, or do I have to do some type of cloning in the Setup/Return to make this work?
I don't believe there is built in functionality to detect that method under test did not change object passed to it.
Options:
make sure that return objects are immutable - either by having them immutable to start with or by returning interface without "set" methods with an instance created via mocks
create separate instance for "expected" and "mocked" values and then compare property-by-property. There are plenty of helper libraries to do so (I like FluentAssertions).
just assert on individual properties instead of comparing objects - works fine for small number of fields.
If possible I'd prefer immutable objects - that prevent possibility of writing wrong code and thus decreases amount of testing needed.
In this case you didn't receive a new data and can verify behavior
Internal state is not valuable in this case
var requestObject = new RequestObject();
var returnObject = new MyReturnObject();
...
var actual = requestHandler.ProcessRequest(requestObject);
Assert.AreSame(returnObject, actual);
mockMapper.Verify(
instance => instance.Map<MyRequestObject>(requestObject),
Times.Once);
Some details
we can't share write access with others, so i assume you have
public class MyRequestObject
{
int RequestInt { get; private set; }
string RequestString { get; private set; }
}
otherwise you always should test for parameter mutation. You can imagine 10 participants called in depth and each of them should have such tests. These tests will weak against changes, they do nothing with new properties.
It is better to have good coding convention and do codereview sometimes. In example someone can randomly remove private from property and it can't be catched with any tests.
There are many good practices in example "write test before of code" and so on

How can factory's have access to other factory's products in abstract factory pattern

In this example for the NYPizzaIngredientFactory, they can only make pizza with ThinCrustDough. How can i make a pizza that could use another factory's ingredients like ThickCrustDough from ChicagoPizzaIngredientFactory. I want to try stay away from builder and stick with abstract factory patterns and factory methods.
Your NYPizzaStore would have to use the ChicagoPizzaIngredientFactory if you want it to be able to use ThickCrustDough.
If you think about the practicality of this, however, it probably doesn't make sense to have them ship you the ingredients from Chicago.
In my mind, you have two options:
Have another factory located in NY that can produce thick dough (e.g. NYThickPizzaIngredientFactory). This is because your interface has a single createDough method that takes no arguments so you can't tell it what type of dough to make. It can only make one.
Alter your interface so that the createDough method accepts arguments that can tell the factory what type of dough to create. This is the one I would recommend.
The type of arguments can also be based on the particular factory. For instance:
//TDoughArts tells you what type of arguments the factory needs in order to make dough.
public interface IPizzaIngredientFactory<TDoughArgs> where TDoughArgs : IDoughArgs
{
//....
IDough CreateDough(TDoughArgs doughArgs);
//....
}
public interface IDoughArgs
{
}
public class NYPizzaDoughArgs : IDoughArgs
{
public enum DoughTypes
{
Thin = 0,
Thick = 1
}
public DoughTypes DoughType { get; set; }
}
public class NYPizzaIngredientFactory : IPizzaIngredientFactory<NYPizzaDoughArgs>
{
//....
public IDough CreateDough(NYPizzaDoughArgs doughArgs)
{
//Make the right dough based on args here
if(doughArgs.DoughType == DoughTypes.Thin)
//...
}
//....
}
I whipped this out in a few minutes so check for consistency, but I think you will get the idea.
You don't have to use generics. You can simply stick with the IDoughArgs interface if you don't want more specificity.
Usage:
var factory = new NYPizzaIngredientFactory();
var args = new NYPizzaDoughArgs();
args.DoughType = NYPizzaDoughArgs.DoughTypes.Thick;
var dough = factory.createDough(args);
The first problem I see is this:
public interface IDoughArgs
{
}
public class NYPizzaDoughArgs : IDoughArgs
{
public enum DoughTypes
{
Thin = 0,
Thick = 1
}
public DoughTypes DoughType { get; set; }
}
IDoughArgs has no members. The class that implements it, NYPizzaDoughArgs, has properties which are not implementations of IDoughArgs. That renders the IDoughArgs interface meaningless.
Additionally, look at this class declaration:
public class NYPizzaIngredientFactory : IPizzaIngredientFactory<NYPizzaDoughArgs>
What class is going to "know" the generic argument and know to create this class as opposed to some other generic implementation? It's going to get confusing when you get to that part. You'll need some sort of factory to create your factory.
Then, if you decide that ingredient factories vary by more than just the type of dough, and you need more generic arguments, it's going to get really messy.
And, what happens if, in addition to having options such as thickness that are specific to just one dough type, you need options that are specific to just one thickness? Perhaps thick dough is only an option if you've selected New York or Chicago style (not European) and stuffed crust is only an option if you've selected a thick crust. That's going to get really difficult to describe with interfaces. It sounds more like data.
Here's a stab at another way to implement this:
public enum PizzaStyle
{
NewYork = 1,
Chicago = 2,
Greek = 4
}
public enum CrustType
{
Thick = 1024,
Thin = 2048,
HandTossed = 4096
}
public enum CrustOption
{
Stuffed = 32768
}
public enum PizzaDoughOption
{
NewYorkThin = PizzaStyle.NewYork + CrustType.Thin,
NewYorkHandTossed = PizzaStyle.NewYork + CrustType.HandTossed,
NewYorkThick = PizzaStyle.NewYork + CrustType.Thick,
NewYorkThickStuffed = NewYorkThick + CrustOption.Stuffed,
ChicagoThin = PizzaStyle.Chicago + CrustType.Thin,
ChicagoHandTossed = PizzaStyle.Chicago + CrustType.HandTossed,
ChicagoThick = PizzaStyle.Chicago + CrustType.Thick,
ChicagoThickStuffed = ChicagoThick + CrustOption.Stuffed,
Greek = PizzaStyle.Greek // only comes one way?
}
There are other ways to represent this same data. Even if there were fifty values in the PizzaDoughOption enumeration, it's probably still easier that way, building a definitive, readable list of valid options, as opposed to trying to represent that in code with a bunch of branches. (If you want to unit test that, you'll end up coding every single combination anyway in unit tests.)
And there are several ways you could use this data. You could present just a big list of options. You could allow users to select from the various options and, as you go, determine whether it matches a valid combination. Or they could select any option and you could narrow the list of options according to which include the desired option. (You want a stuffed crust? Ok, that's either New York thick crust or Chicago thick crust.)
Now, if you need a factory to create dough according to type, you could do this:
public interface IDoughFactory
{
Dough GetDough(PizzaDoughOption doughOption);
}
The implementation might look something like this. To be honest I might use a "factory factory" here, but for now since there are only three types I'll keep it simpler.
public class DoughFactory : IDoughFactory
{
// Each of these also implement IDoughFactory
private readonly NewYorkDoughFactory _newYorkDoughFactory;
private readonly ChicagoDoughFactory _chicagoDoughFactory;
private readonly GreekDoughFactory _greekDoughFactory;
public DoughFactory(
NewYorkDoughFactory newYorkDoughFactory,
ChicagoDoughFactory chicagoDoughFactory,
GreekDoughFactory greekDoughFactory)
{
_newYorkDoughFactory = newYorkDoughFactory;
_chicagoDoughFactory = chicagoDoughFactory;
_greekDoughFactory = greekDoughFactory;
}
public Dough GetDough(PizzaDoughOption doughOption)
{
if (MatchesPizzaStyle(doughOption, PizzaStyle.NewYork))
return _newYorkDoughFactory.GetDough(doughOption);
if (MatchesPizzaStyle(doughOption, PizzaStyle.Chicago))
return _chicagoDoughFactory.GetDough(doughOption);
if (MatchesPizzaStyle(doughOption, PizzaStyle.Greek))
return _greekDoughFactory.GetDough(doughOption);
// Throw an exception or return a default dough type. I'd throw the exception.
}
private bool MatchesPizzaStyle(PizzaDoughOption doughOption, PizzaStyle pizzaStyle)
{
return ((int) doughOptions & (int) pizzaStyle) == (int) pizzaStyle;
}
}
Now your more concrete dough factories (New York, Chicago, Greek) all receive the same PizzaDoughOption. If they care whether thin or thick has been selected, they can handle it. If that option doesn't exist they can ignore it. Even if something has gone wrong in an outer class and somehow someone has invoked GreekDoughFactory with the StuffedCrust option, it won't fail. It just ignores it.
What would be the possible point to all of this?
First, the class creating a pizza has no knowledge of the intricacies of creating the right dough type. It just depends on a dough factory, passes a parameter, and gets the right dough. That's simple and testable.
Second, you don't have to call new anywhere. You can employ dependency injection all the way down. That way the class that depends on the abstract IDoughFactory doesn't know anything about what dependencies DoughFactory has.
Likewise, maybe the concrete dough factories have dependencies of their own and they differ significantly from one to the next. As long as those are getting resolved from the container and injected into DoughFactory, that's fine, and DoughFactory won't know anything about their dependencies.
All of the dependencies are wired up in your DI container, but the classes themselves are small, simple, and testable, depending on abstractions and not coupled to implementations of anything.
Someone might look and this and think it's a little more complicated. What's critical is that not only does it keep individual classes decoupled, but it leaves a path forward for future change. The design of your classes, which shouldn't have to change too much, won't closely mirror the details of specific types of pizzas, which can and should change. You don't want to have to re-architect your pizza application because of a new kind of pizza.

Setting value of private property

I am trying to test my class
public class Parser
{
private static IDictionary<String, Regex> PhrasesToRegexp { get; set; }
public static void InitPhrases(IList<String> Phrases, Boolean useDeclination )
{
throw new NotImplementedException();
}
...
public ParsingResults Find(String source)
{
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(source);
return new ParsingResults(FindUrls(doc), CountPhrases(doc));
}
private IList<String> FindUrls(HtmlDocument source)
{
return source.DocumentNode.SelectNodes("//a[#href]").
Select(link => link.GetAttributeValue("href", "")).ToList();
}
private IDictionary<String, int> CountPhrases(HtmlDocument source)
{
IDictionary<String, int> results = new Dictionary<String, int>();
foreach (String key in PhrasesToRegexp.Keys)
{
results.Add( key , 0 );
}
foreach (HtmlNode node in source.DocumentNode.SelectNodes("//p"))
{
foreach (String phrase in results.Keys)
{
results[phrase] += PhrasesToRegexp[phrase].Matches
(Regex.Replace(node.InnerText, #"<(.|\n)*?>", string.Empty)).Count;
}
}
return results;
}
}
The thing is that property PhrasesToRegexp is (will be) initialized in InitPhrases and I am trying write unit test for method Find. Basicly i need to set value of this private property PhrasesToRegexp. Is there any way to do that? I am no expert in mocks but i think they will not do the trick since this property and tested method are in the same object.
You could add a new constructor specifically for unit tests, but I would advise minimising any changes to your class to make it unit-testable. Specialisations to support unit tests usually mean that you aren't testing the actual code that will run in the final application. The further you specialise it, the harder it is to be sure that the real code is being fully tested, and the more chance there is of introducing unwanted side effects into the code under test.
Instead, (if possible) I try to use the class as a client would - if you construct the instance and call the method as a client would, you shouldn't need to poke about in private state, and your unit test will test exactly what any client code will use. Also, your test is more likely to remain valid/effective if you change the internal workings of the class, as there is no special pathway for unit tests that you can forget to keep in sync with the code changes.
If you prefer to expose the property and prod it directly, then changing it to internal and using InternalsVisibleTo is a standard approach, but it offends my sense of encapsulation as it becomes permanently internal for everybody. How is another programmer to know that you mean "internal for testing" rather than "hey, we're good friends, please party on my internal state as much as you like". What is private there for if we just throw it away when we want to unit test? So another approach, which keeps the code private, is to use a special build for unit testing, which sets a #define to allow you to expose the privates you want to access for tests, while leaving them private in your normal build.
One way is brute force on the property itself (but this can be quite messy):
#if UNIT_TEST
public
#else
private
#endif
int MyPrivateProperty { get; set; }
Or, a cleaner approach (but more work) is to leave the original code unscathed and add access methods, to minimise the chance that you inadvertently break/alter the code under test.
private int MyProperty { get; set; }
#if UNIT_TEST
public int AccessMyProperty
{
get { return(MyProperty); }
set { MyProperty = value; }
}
#endif
In my Unit Test project I've created a MockClass which extends the original class, no methods or properties are rewritten.
Original class: the property which was private is promoted to protected.
Mock class: Created a public method which sets the protected property.
With this approach you don't have to change visibility to internal, which is a lot more visible than protected. Of course it also means that if a developer wants to acces your property he is able to by extending your class, in the same manner as your unit test does.
public class Parser
{
protected static IDictionary<String, Regex> PhrasesToRegexp { get; set; }
...
}
public class MockParser : Parser
{
public MockParser() : base()
{
}
public void AddPhraseToRegexp(String key, Regex value)
{
// Add it
PhrasesToRegexp.Add(key, value);
}
public void CreatePhrasesToRegexp(IDictionary<String, Regex> newDict)
{
// Create a new Dictionary
PhrasesToRegexp = newDict;
}
}
NOTE: this does NOT work for static or sealed classes
This may be possible depending on mocking framework you are using. I usually use Moq or NMock2, and in those cases the viable options are:
1) Make the property internal instead of private, which allows you to set it in unit test. You may have to use InternalsVisibleTo attibute if your unit tests are in separate project.
2) Create a separate constructor for unit test purpoeses that will accept PhrasesToRegexp
1) Instead of private you should declare it as internal.
2) In AssemblyInfo.cs you should add the assembly, from there your class will be accessed like follows
[assembly: InternalsVisibleTo("MainFormUnitTests")]
For me, this problem is arising because you are expressing two different concerns in your parser.
A quick reference cache for your phrases and regex
The parsing logic
I would suggest splitting out these two concerns into two different classes. Besides, you might want to address clearing out the memory of the static dictionary at some point (or invalidating the cache).
If you take the caching logic out behind a ICachePhrasesAndRegex interface then you can easily mock the dependency for testing.

Structuremap and creating objects with initial state

I have an object which needs a dependency injected into it
public class FootballLadder
{
public FootballLadder(IMatchRepository matchRepository, int round)
{
// set initial state
this.matchRepo = matchRepository;
this.round = round;
}
public IEnumerable<LadderEntry> GetLadderEntries()
{
// calculate the ladder based on matches retrieved from the match repository
// return the calculated ladder
}
private IMatchRepository matchRepo;
private int round;
}
For arguments sake, lets assume that I can't pass the round parameter into the GetLadderEntries call itself.
Using StructureMap, how can I inject the dependency on the IMatchRepository and set the initial state? Or is this one of those cases where struggling against the framework is a sign the code should be refactored?
You can always use constructor parameters for default values. I used the following for a default instance of a sqlconnection.
this.For<SqlConnection>().Use(c => new SqlConnection(ConfigurationManager.ConnectionStrings["conn"].ConnectionString));
There are other ways as well but I don't remember them off the top of my head.
EDIT: Here is another way it could be done as well. I found this one from here:
http://www.theabsentmindedcoder.com/2010/05/structure-map-26-constructor-arguments.html
x.For<MatchRepository>().Use<MatchRepository>();
x.For<IFootballLadder>().Use<FootballLadder>()
.Ctor<int>("round")
.Is(3);
If the value of round was determined from a method you could specify it with a lambda expression to load the value like so
.Is(c => c.GetInstance<IRoundProvider>().GetRound())
Hope this makes sense. But to answer your question yes it is possible and pretty easily.
Most DI frameworks allow you to inject primitives in constructors as Spinon showed you. When possible, I try to refactor my code in a way that I don't need complex configurations. Often this makes my application code the most understandable, with the least surprises (low number of WTFs per minute ;-)). You have to balance this out carefully, because sometimes complex configurations could make your application code simpler.
Here are some possible suggestions for refactorings:
1) Use a factory:
Using a factory is useful when clients must control the round value:
public interface IFootballLadderFactory
{
FootballLadder CreateNew(int round);
}
This way you can inject a IFootballLadderFactory and allow clients to call:
var ladder = this.footballLadderFactory.CreateNew(3);
2) Use a property:
You can remove the round argument from the constructor and change it in to a get/set property. This is both useful when clients must be able to control the round value or when using a factory:
public class FootballLadder
{
private IMatchRepository matchRepo;
public FootballLadder(IMatchRepository matchRepository)
{
}
public int Round { get; set; }
}
And implementation of the IFootballLadderFactory for instance could look like this:
public class CastleFootballLadderFactory : IFootballLadderFactory
{
public IWindsorContainer Container;
public FootballLadder CreateNew(int round)
{
var ladder = this.Container.Resolve<FootballLadder>();
ladder.Round = round;
return ladder;
}
}
Or a client could set the Round property:
public class Client
{
public Client(FootballLadder ladder)
{
ladder.Round = 3;
}
}
Please be careful with this last example. The client should normally not have to care about the lifetime of the dependency. In this case, we're changing the state of an injected dependency. This prevents us from changing the lifetime of this dependency, because in that case the state of the ladder instance, could be changed from under the client's feet. Besides this, the FootballLadder class should throw an InvalidOperationException when the Round was never set. I think such a check is nice and clean, but does make you write a bit more code.
3) Inject a IRoundProvider into the FootballLadder constructor:
As Spinon wrote, you can implement a IRoundProvider, but instead of using it in your configuration, you can use it as constructor argument.
public class FootballLadder
{
private IMatchRepository matchRepo;
private int round;
public FootballLadder(IMatchRepository matchRepository,
IRoundProvider roundProvider)
{
this.round = roundProvider.GetRound();
}
}
4) Create a sub type specific for your DI configuration:
public class DIFootballLadder : FootballLadder
{
private const int Round = 3;
public DIFootballLadder(IMatchRepository matchRepository)
: base(matchRepository, Round)
{
}
}
Now you can register the it as follows:
x.For<FootballLadder>().Use<DIFootballLadder>();
Downside of this is that you have this extra code with itself is plain configuration code. Besides that, when the dependencies of the FootballLadder change, you have to change the DIFootballLadder as well.
I hope this helps.

Categories

Resources