It's time for some more seemingly simple questions that I just can't seem to find the answer to.
I'm developing a library with TDD (PHP). To my understanding, when using TDD, you should not write any production code without first writing a failing test to warrant it.
I have a mutator method, that appends data to an array with private visibility. How should I test that? Should I just test the various accessor instead? Should the test for the accessor cover the mutator method?
Is it OK for a test to test an accessor and a mutator, or should these be separate tests?
My library requires a dependency, which I will inject through the constructor. What test code might prompt me to write the constructor code?
Sorry for such noobish questions. I've been studying TDD quite a lot, and thought I had it all figured out, but as soon as I try to make use of it, all these little questions come to mind. Obviously I want to make sure that, I implement it effectively and to the best of my knowledge.
Perhaps I'm being too strict? Perhaps the injection is tested implicitly using a mock and checking expectations of a method that makes use of the injected class?
I understand these questions might be subjective, and the answers might be based on people's opinions, but I'm fine with that. I just want to get started in a way that makes sense and works.
Many thanks in advance.
I would test the setter and getter methods together, because that is by far the simplest way to do it without having to change the visibility of your array, which you shouldn't do. Your injected class will be tested implicitly by these tests.
In general try to write your unit tests from the perspective of another user trying to use your class under test. You need to think, what is this class supposed to do or what is its contract (i.e. this class holds an array of objects that users can add and remove from), then write tests to be certain it satisfies that contract. After that, write just enough code to get the test to pass.
Related
I've just started with unit testing and I'm getting a bit confused and a bit overwhelmed when the subject is testing the models. I currently have some ActiveRecord models with setters and getters. Most of them are simply to encapsulate data, only a few of them bring something new, like for instance a getFullName() method that returns the concatenation of the firstName and lastName fields.
So what should I test? Should I test every single property assignment or should I test only the special methods like getFullName()? To what extent should I go? When should I test the class itself and when should I actually test the database insert? What about the validation already present in the entity, should I take that into account?
What overwhelms me is the amount of tests it seems I would need for an entity with lots of fields. Is there a way around it?
Examples would be specially appreciated!
Write the tests that you need to give you confidence that your program works properly.
There are people that would argue that if the class has no business logic there is no need to write tests for it. By that argument, then your simple getters and setters don't need to be tested. You only write tests for the parts of the code that have "business logic".
However the other side of the argument is that if you write the code, you should write a test for it. By that argument, you should write a test for them. The test will end up being really trivial. You instantiate the object, set a value with the setter and then assert that the value is then returned with the getter. You end up with a lot of simple tests and it can get tedious to write.
I am in the second camp and have found that if something is hard to test or becomes a pain for testing it is a sign that I have an issue with my design. In this case, you might have accessor methods for things that aren't needed. What likely happened is that you have all your properties in your data object and "need" to have a getter and setter for each of them. But do you really?
In your question, you mentioned that you have a getFullName method. So do you really need methods for getFirstName and getLastName? Why would the data in the object change during the rendering of the page? Why not forgo setters and make the data record 'immutable' so that an update is done by sending a new object to the database for update/create?
I would bet that the reason that you are having this question is that you wrote this code and now are trying to go back and write tests for it. You have this data object and automatically created getters and setters for everything. Then wrote extra methods that you need as you were using it (like the getFullName method). Rather I would recommend that you only create the accessors as you need them. Then you create the test at the time and you will find that the list of functions is substantially smaller. You might have a handful of methods that get the combinations of data that you require as well as a bulk method for getting all the data in a particular form (ie json).
This is my current system for a framework that I'm making:
I create an object upon a request to access a non-existing property, that has the name of an existing class through the __get function defined in the Core class. The Core class extends every class.
So it works like this:
class Someclass extends Core
{
public function classmethod()
{
$this->otherclass->method();
}
}
This works exactly how I want it to work. However, I have no idea (after a lot of frustration) how to edit/create properties of the object, using this system.
So something like this would't work.
$this->view->somevar = "newvalue"; // this doesn't work.
I guess it has to do something with the __set function, but I failed to find out.
I received the following suggestions how to tackle this problem:
Dependency injection, Namespaces, Singleton pattern.
I would love to see how to implement what I'm trying to do using one of these patterns.
I have no idea which to choose in order to achieve my simple problem: Use objects in other classes, so i don't need to put anything into __construct's parameters or using global variables.
I am using __autoload.
I hope i can tackle this problem with your help.
First of all, the architecture you're attempting is extremly bad. Aparently you are using "magic" to create objects attached as properties to other objects. Which is bad, because if you use _get/_set, you will end up in problems sooner rather than later. Also extending from a common parent is a bad thing because it generates huge inheritance trees, and it allows most of the objects to have more than one responsability.
Before starting a framework, you might want to look over: SOLID
Now coming back to your question, if you use __get for getting a value, you can as well use __set for setting a value.
__construct method is there in order to allow you to initialize the object with all the data it needs in order to fulfill his sole purpose. Avoiding the __construct is kinda stupid, and defeats the purpose. You might want to pay attention to the D in SOLID in order to see what Dependency Inversion really is and to understand it.
Using __set loses completely the ability to typehint interfaces and so on. Therefore the code can become really buggy and ijcredibly hard to follow, since the flow is not so well defined, and the allocation is done in the back via magic. Also i can come up with 1 million other reason for which the architecture you are trying to use is wrong, but i will leave that for another time.
I didn't find a similar question, so I apologize if it already exists.
In my system I want a number of function libraries to ease a number of tasks across the whole system. That could be validating an e-mail. There's no reason to write the full regular expression each time if I can have a function do it, so I only need to change things and fix errors in one place.
Say I write a class called Files_Tools.
I can make it work both by dependency injecting an instance of this class into the objects that needs functions from this class. But I can also write the Files_Tools class with static functions and access them with the scope resolution operator. But as I have come to understand one of the major things about DI (dependency injection) is to avoid this kind of "global use". So my logic tells me to go with the DI approach. Yet, it still doesn't feel "right" that I'm doing it this way.
So my question is - What is regarded as the most correct way to create a toolset for a system? First of all, is it to make it as a class, instead of just plain functions? And then if it really is a class is the way to go, should I aim for the SRO or DI?
I understand there is probably not a definitive answer to this question, but I want to know if I'm completely off track or heading where many other coders would have done too.
Thanks in advance :)
DI makes it easier to unit test your classes and methods without dependency on the injected class... you can mock the injected object and manipulate its returns as appropriate for your tests. Scope resolution leaves you with this dependency so the tests aren't fully isolated.
Many of my earlier projects use static classes for such functionality, and trying to write unit tests for them 6 years on is now a real chore because I didn't use DI.
I'm designing a class that has two dependencies. One of the dependency classes has been written and tested. The other has not yet been written.
It has occurred to me because the remaining dependency will be written to facilitate the class that will use it, that I should write the latter first, and design the interface of the former as I go along, learning what it should do.
That seems to me to be a great way to make code. After all, as long as the main class gets a mock in its constructor, I can write it and test it without it being aware that its dependency doesn't exists, then I can create the dependency once I am sure I know what I need.
So: how do I do this? Create a skeleton class that I modify as I go along. Perhaps something like:
class NonExistantSkeleton
{
public function requiredMethod1()
{
}
public function newlyDiscoveredRequirement()
{
}
}
and then mock it using PHPUnit, and setting up stubs, etc, to keep my class under development happy?
Is this the way to go?
It seems like a nice way to develop code - and seems to me to make more sense than developing a dependency, without really knowing for sure how it's going to be used.
In short:
Yes. At least thats what I'm doing right now.
Longer Version:
If the expected collaborators of your class don't exist at the point in time where you need them in your tests for the class you are building you have a few options:
Mock non existing classes (which phpunit can do)
Create class skeletions and mock those
Just create interfaces and get mocks for those (which phpunit can do too)
Maybe you don't need any of the above depending on the object
If you programm against an interface anyways than all you need to do is to create that interface and tell PHPUnit to create a stub/mock from it
+No new class without a test
+Using interfaces when appropriate is considered nicer/better than just hinting against classes
When mocking non existing classes you get some drawbacks that I don't like:
-High mock maintenance cost
-Chaning the methods on that classes is slow and tedious
-If you created the class you should rework the mocks again
so I'd advice against that.
The middle way would be to just create the empty class skeleton with its method and use those for mocking.
I quite like that way in cases where there is no interface to hint against as It is fast and creates stable test code.
Having barebone classes with public apis, for me, is no violation of TDD.
There are classes you don't need to mock.
Data transfer objects and Value Objects can always be created anywhere using the new in your production code so your tests also can just the the real objects.
It helps to keep your tests a little cleaner as you don't need to mock/expect a lot of getter/setter methods and so on.
If you follow a test-driven development methodology then the usual approach is as follows:
Figure out what your classes are meant to do, and what their public-facing APIs should be.
Implement "empty" classes that consist of nothing but the public methods signitures with empty bodies (as you have done in the code example you gave).
Work out an implementation strategy. This means working out which classes are dependant on each other and implementing them in an order that means that dependant classes aren't implemented until the classes it depends on are finished, or at least sufficiently functional to develop against. This means doing the classes with no dependencies first, then the classes that depend only on the completed classes, and so on.
Write your tests. It's possible to write the tests now because you know what the black box for your classes look like, what they need to take as input and what they're supposed to return as output.
Run the tests. You should get 0% success, but also 100% code coverage. This is now your baseline.
Start to implement your classes according to your implementation strategy. Run your unit tests from time to time during this process, say once you've got a class completed, to make sure that it meets its specification as laid down in the unit test. Ideally, each test should show an increase in test passes whilst maintaining 100% code coverage.
EDIT: As edorian pointed out, PHP interfaces are a huge help here because PHPUnit can generate mocks and stubs from interfaces as well as from classes. They're also an excellent tool in reducing coupling and improving substitutability in general. They allow you to substitute any class that implements the expected interface, instead of just subclasses of the expected class.
In a theoretical database access class, I found that there are quite a few helper functions that I use in the class, which have nothing to do the class's instance (and others, that could be manipulated to be unrelated to the class's instance using dependency injection).
For example, I have a function that gets a string between two other strings in a variable. I've been thinking of moving that to a String_Helper class, or something of the sort. This function has already been made static.
Also, I have a function that queries a database, query($sql). The connection details are provided by the instance, but I've been considering making it static, and using query($sql, $connection). Developers would then be able to call it statically and not need to instantiate the database class at all.
For me, the questions are:
Is it worth it to do something like this? Functions like the query function make me wonder if this is not just me trying to make everything as static as possible, without any real need to. Under what circumstances would you consider this useful?
I know static functions are harder to test, but if I make sure that their code is completely dependency free (or uses dependency injection where necessary), then they're just as easy to test as everything else, surely?
It isn't a concern at the moment, but if, in the future, I decided to extend the classes with the static functions, it would be impossible for me to make the current code use my extended functions. I've thought of Singletons, but the same problem arises: the code would be calling Singleton_Class::getInstance(), and not My_Extended_Singleton_Class::getInstance(). Dependency Injection seems to be the only way to solve this issue, but it might lead to a clunkier API, as every dependency has to be given to an object on __construct().
I have a container class, which holds certain pieces of information statically so that they can be accessed anywhere in the script (global scope). If I can't use static functions or singletons, a class that contained instances of different variables would be great. One could use for example Container::$objects['MyClass'] = $MyClass_object;, and then the rest of the code could just access Container::$objects['MyClass']. If I extended the MyClass class, I could use Container::$objects['MyClass'] = $MyExtendedClass_object;, and the code that used Container::$objects['MyClass'] would use MyExtendedClass, rather than MyClass. This is by far the best way to do it, in my opinion, but I'd like to know what you think about it.
Ok, let me answer these one by one...
1. Is it worth doing something like this
Yes and no. Splitting out the helper functions into their own classes is a good idea. It keeps the "scope" of each of the classes rigidly defined, and you don't get creap. However, don't make a method static just because you can. The query method is there to make your life easier by managing the connection, so why would you want to lose that benefit?
2. They are harder to test
They are not harder to test. Static methods that depend on state are harder to test (that access static member variables or global variables). But static methods in general are just as easy to test as instance methods (in fact, they can be easier since you don't need to worry about instantiation).
3. Extending the classes
This is a valid concern. If you put String_Helper::foo() in the class itself, you'll run into issues. But an option would be to set the name of the string helper as a class variable. So you could then do {$this->stringHelper}::foo() (note, PHP 5.3 only). That way to override the class, all you need to do is change the string helper class in that instance. The Lithium framework does this a lot...
4. Global Registry
I would stay away from this. You're basically just making every class a singleton without enforcing it. Testing will be a nightmare since you're now dependent on global scope. Instead, I'd create a registry object and pass it to classes via the constructor (Dependency Injection). You still accomplish the same thing since you have a store for the objects/classes, but you're no longer dependent on a global scope. This makes testing much easier.
In general
When you're looking at doing things like this, I like to stop when I hit questions like this. Stop and sit down and think *What actual problem am I trying to solve?". Enumerate the problem explicitly. Then pull our your supposed solutions and see if they actually solve them. If they do, then think about the future and if those solutions are really maintainable in the long run (Both from a bug fix standpoint, and with respect to feature additions). Only if you're happy with both of those answers should you even consider doing it. Oh, and also remember to keep it simple. Programming is not about making the most complex, most clever or most amazing solution. It's about making the simplest solution that solves the problem...
I hope that helps...
Good Luck!