Unit testing factory methods which have a concrete class as a return type - unit-testing

So I have a factory class and I'm trying to work out what the unit tests should do. From this question I could verify that the interface returned is of a particular concrete type that I would expect.
What should I check for if the factory is returning concrete types (because there is no need - at the moment - for interfaces to be used)? Currently I'm doing something like the following:
[Test]
public void CreateSomeClassWithDependencies()
{
// m_factory is instantiated in the SetUp method
var someClass = m_factory.CreateSomeClassWithDependencies();
Assert.IsNotNull(someClass);
}
The problem with this is that the Assert.IsNotNull seems somewhat redundant.
Also, my factory method might be setting up the dependencies of that particular class like so:
public SomeClass CreateSomeClassWithDependencies()
{
return new SomeClass(CreateADependency(), CreateAnotherDependency(),
CreateAThirdDependency());
}
And I want to make sure that my factory method sets up all these dependencies correctly. Is there no other way to do this then to make those dependencies public/internal properties which I then check for in the unit test? (I'm not a big fan of modifying the test subjects to suit the testing)
Edit: In response to Robert Harvey's question, I'm using NUnit as my unit testing framework (but I wouldn't have thought that it would make too much of a difference)

Often, there's nothing wrong with creating public properties that can be used for state-based testing. Yes: It's code you created to enable a test scenario, but does it hurt your API? Is it conceivable that other clients would find the same property useful later on?
There's a fine line between test-specific code and Test-Driven Design. We shouldn't introduce code that has no other potential than to satisfy a testing requirement, but it's quite alright to introduce new code that follow generally accepted design principles. We let the testing drive our design - that's why we call it TDD :)
Adding one or more properties to a class to give the user a better possibility of inspecting that class is, in my opinion, often a reasonable thing to do, so I don't think you should dismiss introducing such properties.
Apart from that, I second nader's answer :)

If the factory is returning concrete types, and you're guaranteeing that your factory always returns a concrete type, and not null, then no, there isn't too much value in the test. It does allows you to make sure, over time that this expectation isn't violated, and things like exceptions aren't thrown.
This style of test simply makes sure that, as you make changes in the future, your factory behaviour won't change without you knowing.
If your language supports it, for your dependencies, you can use reflection. This isn't always the easiest to maintain, and couples your tests very tightly to your implementation. You have to decide if that's acceptable. This approach tends to be very brittle.
But you really seem to be trying to separate which classes are constructed, from how the constructors are called. You might just be better off with using a DI framework to get that kind of flexibility.
By new-ing up all your types as you need them, you don't give yourself many seams (a seam is a place where you can alter behaviour in your program without editing in that place) to work with.
With the example as you give it though, you could derive a class from the factory. Then override / mock CreateADependency(), CreateAnotherDependency() and CreateAThirdDependency(). Now when you call CreateSomeClassWithDependencies(), you are able to sense whether or not the correct dependencies were created.
Note: the definition of "seam" comes from Michael Feather's book, "Working Effectively with Legacy Code". It contains examples of many techniques to add testability to untested code. You may find it very useful.

What we do is create the dependancies with factories, and we use a dependancy injection framework to substitute mock factories for the real ones when the test is run. Then we set up the appropriate expectations on those mock factories.

You can always check stuff with reflection. There is no need to expose something just for unit tests. I find it quite rare that I need to reach in with reflection and it may be a sign of bad design.
Looking at your sample code, yes the Assert not null seems redundant, depending on the way you designed your factory, some will return null objects from the factory as opposed to exceptioning out.

As I understand it you want to test that the dependencies are built correctly and passed to the new instance?
If I was not able to use a framework like google guice, I would probably do it something like this (here using JMock and Hamcrest):
#Test
public void CreateSomeClassWithDependencies()
{
dependencyFactory = context.mock(DependencyFactory.class);
classAFactory = context.mock(ClassAFactory.class);
myDependency0 = context.mock(MyDependency0.class);
myDependency1 = context.mock(MyDependency1.class);
myDependency2 = context.mock(MyDependency2.class);
myClassA = context.mock(ClassA.class);
context.checking(new Expectations(){{
oneOf(dependencyFactory).createDependency0(); will(returnValue(myDependency0));
oneOf(dependencyFactory).createDependency1(); will(returnValue(myDependency1));
oneOf(dependencyFactory).createDependency2(); will(returnValue(myDependency2));
oneOf(classAFactory).createClassA(myDependency0, myDependency1, myDependency2);
will(returnValue(myClassA));
}});
builder = new ClassABuilder(dependencyFactory, classAFactory);
assertThat(builder.make(), equalTo(myClassA));
}
(if you cannot mock ClassA you can assign a non-mock version to myClassA using new)

Related

In a C++ unit test context, should an abstract base class have other abstract base classes as function parameters?

I try to implement uni tests for our C++ legacy code base. I read through Michael Feathers "Working effectively with legacy code" and got some idea how to achieve my goal. I use GooleTest/GooleMock as a framework and already implemented some first tests involving mock objects.
To do that, I tried the "Extract interface" approach, which worked quite well in one case:
class MyClass
{
...
void MyFunction(std::shared_ptr<MyOtherClass> parameter);
}
became:
class MyClass
{
...
void MyFunction(std::shared_ptr<IMyOtherClass> parameter);
}
and I passed a ProdMyOtherClass in production and a MockMyOtherClass in test. All good so far.
But now, I have another class using MyClass like:
class WorkOnMyClass
{
...
void DoSomeWork(std::shared_ptr<MyClass> parameter);
}
If I want to test WorkOnMyClass and I want to mock MyClass during that test, I have to extract interface again. And that leads to my question, which I couldn't find an answer to so far: how would the interface look like? My guess is, that it should be all abstract, so:
class IMyClass
{
...
virtual void MyFunction(std::shared_ptr<IMyOtherClass> parameter) = 0;
}
That leaves me with three files for every class: all virtual base interface class, production implementation using all production parameters and mock implementation using all mock parameters. Is this the correct approach?
I only found simple examples, where function parameters are primitives, but not classes, which in turn need tests themselves (and may therefore require interfaces).
TLDR in bold
As Jeffery Coffin has already pointed out, there is no one right way to do what you're seeking to accomplish. There is no "one-size fits all" in software, so take all these answers with a grain of salt, and use your best judgement for your project and circumstances. That being said, here's one potential alternative:
Beware of mocking hell:
The approach you've outlined will work: but it might not be best (or it might be, only you can decide). Typically the reason you're tempted to use mocks is because there's some dependency you're looking to break. Extract Interface is an okay pattern, but it's probably not resolving the core issue. I've leaned heavily on mocks in the past and have had situations where I really regret it. They have their place, but I try to use them as infrequently as possible, and with the lowest-level and smallest possible class. You can get into mocking hell, which you're about to enter since you have to reason about your mocks having mocks. Usually when this happens its because there's a inheritance/composition structure and the base/children share a dependency. If possible, you want to refactor so that the dependency isn't so heavily ingrained in your classes.
Isolating the "real" dependency:
A better pattern might be Parameterize Constructor (another Michael Feathers WEWLC pattern).
WLOG, lets say your rogue dependency is a database (maybe it's not a database, but the idea still holds). Maybe MyClass and MyOtherClass both need access to it. Instead of Extracting Interface for both of these classes, try to isolate the dependency and pass it in to the constructors for each class.
Example:
class MyClass {
public:
MyClass(...) : ..., db(new ProdDatabase()) {}; // Old constructor, but give it a "default" database now
MyClass(..., Database* db) : ..., db(db) {}; // New constructor
...
private:
Database* db; // Decide on semantics about owning a database object, maybe you want to have the destructor of this class handle it, or maybe not
// MyOtherClass* moc; //Maybe, depends on what you're trying to do
};
and
class MyOtherClass {
public:
// similar to above, but you might want to disallow this constructor if it's too risky to have two different dependency objects floating around.
MyOtherClass(...) : ..., db(new ProdDatabase());
MyOtherClass(..., Database* db) : ..., db(db);
private:
Database* db; // Ownership?
};
And now that we see this layout, it makes us realize that you might even want MyOtherClass to simply be a member of MyClass (depends what you're doing and how they're related). This will avoid mistakes in instantiating MyOtherClass and ease the burden of the dependency ownership.
Another alternative is to make the Database a singleton to ease the burden of ownership. This will work well for a Database, but in general the singleton pattern won't hold for all dependencies.
Pros:
Allows for clean (standard) dependency injection, and it tackles the core issue of isolating the true dependency.
Isolating the real dependency makes it so that you avoid mocking hell and can just pass the dependency around.
Better future proofed design, high reusability of the pattern, and likely less complex. The next class that needs the dependency won't have to mock themselves, instead they just rope in the dependency as a parameter.
Cons:
This pattern will probably take more time/effort than Extract Interface. In legacy systems, sometimes this doesn't fly. I've committed all sorts of sins because we needed to move a feature out...yesterday. It's okay, it happens. Just be aware of the design gotchas and technical debt you accrue...
It's also a bit more error prone.
Some general legacy tips I use (the things WEWLC doesn't tell you):
Don't get hell-bent about avoiding a dependency if you don't need to avoid it. This is especially true when working with legacy systems where refactorings are risky in general. Instead, you can have your tests call an actual database (or whatever the dependency is), but have the test suite connect to a small "test" database instead of the "prod" database. The cost of standing up a small test db is usually quite small. The cost of crashing prod because you goofed up a mock or a mock fell out of sync with reality is typically a lot higher. This will also save you a lot of coding.
Avoid mocks (especially heavy mocking) where possible. I am becoming more and more convinced as I age as a software engineer that mocks are mini-design smells. They are the quick and dirty: but usually illustrate a larger problem.
Envision the ideal API, and try to build what you envision. You can't actually build the ideal API, but imagine you can refactor everything instantly and have the API you desire. This is a good starting point for improving a legacy system, and make tradeoffs/sacrifices with your current design/implementation as you go.
HTH, good luck!
The first point to keep in mind is that there probably is no one way that's right and the others wrong--any answer is a matter of opinion as much as fact (though the opinions can be informed by fact).
That said, I'd urge at least a little caution against the use of inheritance for this case. Most such books/authors are oriented pretty heavily toward Java, where inheritance is treated as the Swiss army knife (or perhaps Leatherman) of techniques, used for every task where it might sort of come close to making a little sense, regardless of whether its really the right tool for the job or not. In C++, inheritance tends to be viewed much more narrowly, used only when/if/where there's nearly no alternative (and the alternative is to hand-roll what's essentially inheritance on your own anyway).
The primary unique feature of inheritance is run-time polymorphism. For example, we have a collection of (pointers to) objects, and the objects in the collection aren't all the same type (but are all related via inheritance). We use virtual functions to provide a common interface to the objects of the various types.
At least as I read things, that's not the case here at all though. In a given build, you'll deal with either mock objects or production objects, but you'll always know at compile time whether the objects in use are mock or production--you won't ever have a collection of a mixture of mock objects and production objects, and need to determine at run time whether a particular object is mock or production.
Assuming that's correct, inheritance is almost certainly the wrong tool for the job. When you're dealing with static polymorphism (i.e., the behavior is determined at compile time) there are better tools (albeit, ones Feather and company apparentlyy feel obliged to ignore, simply because Java fails to provide them).
In this case, it's pretty trivial to handle all the work at build time, without polluting your production code with any extra complexity at all. For one example, you can create a source directory with mock and production subdirectories. In the mock directory you have foo.cpp, bar.cpp and baz.cpp that implement the mock versions of classes Foo, Bar and Baz respectively. In the production directory you have production versions of the same. At build time, you tell the build tool whether to build the production or mock version, and it chooses the directory where it gets the source code based on that.
Semi-unrelated aside
I also note that you're using a shared_ptr as a parameter. This is yet another huge red flag. I find uses for shared_ptr to be exceptionally rare. The vast majority of times I've seen it used, it wasn't really what should have been used. A shared_ptr is intended for cases of shared ownership of an object--but most use seems to be closer to "I haven't bothered to figure out the ownership of this object". The shared_ptr isn't all that huge of a problem in itself, but it's usually a symptom of larger problems.

Local objects impact on Mocking

Ive recently entered into the world of mocking using jMock - in particular mocking in regards to db. Ive read some posts on how its not possible to (easily) mock a local object contained in a class / method. As Ive never actually done any proper TDD / mocking, Ive always defined objects such as 'ResulSet' in my methods where appropriate. Therefore my question is, when Im going forward with future DB classes / methods, should I define ResultSet as a field, and then have an appropriate Setter Method as a means to access it for testing?
If I should, is this still reasonable considering I probably wouldnt use this setter method for anything else but testing?
Essentially, am I to define all objects with setter methods to aid mocking?
I saw this post: Mocking methods of local scope objects with Mockito and it seems to suggest what Ive said above is acceptable.
I know it seems like a basic question, but I dont want to form bad habits early on.
What you have in the post that you've mentioned is not a good way to go. I suggest starting your TDD adventure without mocking. Start with test-first approach and you will end up with design, which does not require such hideous testing (e.g. partial mocking). Then start mocking, but remember: only mock what you own (so if ResultSet is a JDBC class, you definately should not mock it).
You shouldn't be mocking at that level. Basically the idea is that you have interfaces that acts as a facade on database and ORM operations.
interface IFetchUsers {
UserList GetAll();
User GetById(int id);
}
interface ICalculateDebt {
float GetDebt(int accountId);
}
interface IPersistOrder {
void Save(Order order);
}
(forgive syntax errors, it's been a long time since I've done Java.)
These are injected via the constructor into your other classes and become trivial to mock, or even stub.
Then, for actual db code you just implement these interfaces. You can even put all implementations in a single class.
And that's it. No need to get fancy, but if you do want to get into fancier versions of this look into the repository design pattern (though I would argue that its not really necessary if using a good ORM).

Is it bad practice to unit test a method that is calling another method I am already testing?

Consider you have the following method:
public Foo ParseMe(string filepath)
{
// break up filename
// validate filename & extension
// retrieve info from file if it's a certain type
// some other general things you could do, etc
var myInfo = GetFooInfo(filename);
// create new object based on this data returned AND data in this method
}
Currently I have unit tests for GetFooInfo, but I think I also need to build unit tests for ParseMe. In a situation like this where you have a two methods that return two different properties - and a change in either of them could break something - should unit tests be created for both to determine the output is as expected?
I like to err on the side of caution and be more wary about things breaking and ensuring that maintenance later on down the road is easier, but I feel very skeptical about adding very similar tests in the test project. Would this be bad practice or is there any way to do this more efficiently?
I'm marking this as language agnostic, but just in case it matters I am using C# and NUnit - Also, I saw a post similar to this in title only, but the question is different. Sorry if this has already been asked.
ParseMe looks sufficiently non-trivial to require a unit test. To answer your precise question, if "you have a two methods that return two different properties - and a change in either of them could break something" you should absolutely unit test them.
Even if the bulk of the work is in GetFooInfo, at minimum you should test that it's actually called. I know nothing about NUnit, but I know in other frameworks (like RSpec) you can write tests like GetFooInfo.should be_called(:once).
It is not a bad practice to test a method that is calling another method. In fact, it is a good practice. If you have a method calling another method, it is probably performing additional functionality, which should be tested.
If you find yourself unit testing a method that calls a method that is also being unit tested, then you are probably experiencing code reuse, which is a good thing.
I agree with #tsm - absolutely test both methods (assuming both are public).
This may be a smell that the method or class is doing too much - violating the Single Responsibility Principle. Consider doing an Extract Class refactoring and decoupling the two classes (possibly with Dependency Injection). That way you could test both pieces of functionality independently. (That said, I'd only do that if the functionality was sufficiently complex to warrant it. It's a judgment call.)
Here's an example in C#:
public interface IFooFileInfoProvider
{
FooInfo GetFooInfo(string filename);
}
public class Parser
{
private readonly IFooFileInfoProvider _fooFileInfoProvider;
public Parser(IFooFileInfoProvider fooFileInfoProvider)
{
// Add a null check
_fooFileInfoProvider = fooFileInfoProvider;
}
public Foo ParseMe(string filepath)
{
string filename = Path.GetFileName(filepath);
var myInfo = _fooFileInfoProvider.GetFooInfo(filename);
return new Foo(myInfo);
}
}
public class FooFileInfoProvider : IFooFileInfoProvider
{
public FooInfo GetFooInfo(string filename)
{
// Do I/O
return new FooInfo(); // parameters...
}
}
Many developers, me included, take a programming by contract approach. That requires you to consider each method as a black box. If the method delegates to another method to accomplish its task does not matter, when you are testing the method. But you should also test all large or complicated parts of your program as units. So whether you need to unit test the GetFooInfo depends on how complicated that method is.

Mocking SUT itself

Sometimes I feel the desire of mocking the subject under test itself, I know it looks strange.
Here is the example. I use C#, but it doesn't matter. Imagine you have a class managing some collection. It has methods
public void Insert(int position, T element)
and
public void Delete(int position)
The logic of these methods is not very simple. Besides modifying a collection they can, for example, raise events, or subscribe for/unsubscribe from events, or acquire/release resources, or perform computations. These methods are covered with unit tests checking this functionality.
Now you add a method
public void Replace(int position, T element)
{
Delete(position);
Insert(position, element);
}
I am not completely sure, but to me, it’s not worth testing all those things again for this method. Instead, it makes sense to check if this method really calls the two first.
If the first two methods belonged to another class or interface, it would easy using modern mocking frameworks. But these methods belong to SUT.
Is it possible to do what I want? If not, then why? Is it an unintended flaw of the mocking approach or is it by design. If first, are there workarounds? If second, how should I design and test the described program?
I'm not sure what framework you are using, but I was able to do this in Rhino.Mocks. Instead of instantiating my SUT, I created a stub of it (note that I am not creating a stub of the interface, but of the object itself). The stub will still run the SUT's code, but will also keep track of calls for me.
//Create a stub of my SUT, passing the constructor arguments to GenerateStub()
_sut = MockRepository.GenerateStub<SutClass>(_mockedDependency);
This allows me to assert things like...
_sut.AssertWasCalled(x => x.DoTheStuff(_argObject1, _argObject2),
o => o.Repeat.Once());
Pretty nifty. Now I just need to make sure I don't abuse it ;)
Edit:
I should add that to test if the method DoTheStuff was called, it looks like it may need to be overridable (virtual in C#). I thought it wouldn't be necessary, but a test I wrote the other day suggests the opposite. Let me know if I'm wrong.
First of all, yes it can be done, at least in FakeItEasy.
Second of all, it's probably not a good idea. I say probably because there are cases where it's at least not a very bad idea. In your example above I'd say it's probably a bad idea but I'm not sure that's a real world example. It's a bad idea since the replace method could just as well be an extension method for your class and that way it will be very easy to test.
However if you decide that it is a good idea in your case this is how you'd do it in FakeItEasy (make sure that the methods you want to assert on are virtual):
// In your set up
var sut = A.Fake<MySut>();
A.CallTo(sut).CallsBaseMethod();
// In your test of the Replace-method
A.CallTo(() => sut.Delete(thePosition)).MustHaveHappened();
I'm not sure if it's very easy to do this in other mocking frameworks but this would probably point you in the right direction.
As I said, it's probably not a good idea in most cases but I have used this technique myself and it can be useful.

TDD: Adding a method to test state

So, I'm starting to write some logic for a simple program (toy game on the side). You have a specific ship (called a setup) that is a ship + modules. You start with an empty setup based off a ship and then add modules to that setup. Ships also have a numbered array of module positions.
var setup = new Setup(ship); // ship is a stub (IShip) defined someplace else
var module = new Mock<IModule>().Object;
setup.AddModule(module, 1); // 1 = which position
So, this is the code in my test method. I now need to assert on this code. Well, I need a getter method right?
Assert.AreEqual(module, setup.GetModule(1));
This might sound really dumb and I'm worrying about nothing, but for some stupid reason I'm concerned with adding a method just to assert that a test passed.
Is this fine and is in fact part of the design process that TDD is pushing out? For instance I know I need an AddModule method because I want to test it, and the fact that this requires a GetModule method to test is simply an evolution of my design via TDD.
Or is this kind of a smell because I don't even know if I'll really need GetModule in my code and it will only be used in a test?
For example, adding a module is going to ultimately affect different stats of a setup (armor, shield, firepower, etc). The thing is those are going to be complex, and I wanted to start with a simple test. But in the end, those are the public attributes I care about -- a setup is defined by its stats, not by a list of modules.
Interesting question. I'm glad to hear you're writing the tests first.
If you let the design manifest itself through the tests, you're more likely to build only the parts you'll need. But is this the best design? Maybe not, but don't let that discourage you -- your add method works!
It may be too early to tell if you'll need the GetModule method later. For now, build up the functionality you need and go green, then slowly refactor it (going from red to green again) to get the design you want.
Part of evolving the design is to start with baby steps like a simple method and then grow into the complex stats (eventually dropping this method and changing the test) when enough supports it. When doing TDD, don't expect that the first test you write is targeting the ideal interface. It is OK to have some messiness that will get dropped as you evolve the design.
That being said, if you see no public purpose to the method, try to limit its visibility as much as is reasonable to the test code. Although even that should eventually go away as you get to build out the rest of the system and have something real to test as a side effect of the set method.
I would be wary of introducing a public method in my class that is only used for testing.
There are various ways how you could test this:
Reflection: The GetModule method is a private method in your class (this could also work if your 'stats' are private) and you can access it in your test method via reflection. This will work well, the only trouble is you will not get any compiler errors if you change the name of the private method or add / delete some variables (but, of course, your test will fail and you will know early)
Inheritance: The GetModule method could be protected (only inheritance visible) and your test class could inherit from the main class. This way your test class gets access to this method, but this is not really exposed to the outside world.
Assert the side-effect: This is where you really think about what it means to add a module to the system. If it is going to affect some 'stats' as you put it, you could write tests which assert that the stats are appropriately modified.