Test Driven Development and KISS - php

For example I want to design a Job entity. Job has a status and I need to mark a Job as done.
I wrote a markDone() method and I want to test it. So to do an assertion I need one more method - isDone(). But at the moment I don't use isDone() method in the my code.
Is it ok to write such a useless methods to please a TDD?

Is it ok to write such a useless methods to please a TDD?
Yes, but maybe not.
The yes part: you are allowed to shape your design in such a way that testing is easier, including creating methods specifically for observability. Such things often come in handy later when you are trying to build views to understand processes running in production.
The maybe not part: What's Job::status for? What observable behavior(s) in the system change when that status is set to done? What bugs would be filed if Job::markDone were a no-op? That's the kind of thing you really want to be testing.
For instance, it might be that you need to be able to describe the job as a JSON document, and changing the job status changes the value that appears in the JSON. Great! Test that.
job.markDone()
json = job.asJson()
assert "DONE".equals(json.getText("status))
In the domain-layer / business-logic, objects are interesting for how they use their hidden data structures to respond to queries. Commands are interesting, not because they mutate the data structure, but because the mutated data structure produces different query results.

If the method has no use outside of testing, I'd avoid writing it since there's probably another way that you can check whether or not the job is done. Is the job's status public, or do you have a method that returns the job's status? If so, I'd use that to test whether markDone() is working properly. If not, you can use reflection to check the value of a private or protected object property.

Can `isDone()' just reside in the test project and not the production code? That way, you wouldn't have useless production code just for the sake of testing.

Related

TDD: Constructor Injection and Mutator Testing

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.

Laravel: What is the best practice in testing controller

I'm using laravel 4 and trying to write a test for controller with a mock up of the business logic which pass some fake data.
Then I encounter errors in rendering view due to missing of variables.
First of all, I didn't expect that the view will be rendered, so I didn't care to pass the exact data structure that is needed.
Should I pass the correct data structure to the view or is there a way to stop view from rendering in the test? Which is the better practice and why?
Moreover, after attempting to imitate data structure passing by business logic, there is still error cause by permission of user.
The result temp file of the view has been generated by web user (www-data) and I don't have permission to modify it.
I know, I can just chmod 777, but this is clearly not a good practice, if I have to do that for every time I want to run the test.
Thanks in advance
I suppose your controllers are not messed up. Every logic should be injected through constructor or resolved from the IOC. Mock external classes and bind mocked instances on your test setUp. Facades already have support for Mockery. You can use XXX::shouldReceive().
Also, I suggest you to take a look at Illuminate\Foundation\Testing\TestCase. It has helper methods like assertViewHas, assertSessionHas, assertRedirectedTo etc. With these, testing your controller will be really easy.
After all, best thing to do for you would be reading "Laravel Testing Decoded" by Jeffrey Way. It'a short and amazing book. https://leanpub.com/laravel-testing-decoded
i had a similar problem with the view breaking up while testing. in my case it was a foreach loop, that didn't get the right structure, so i changed my mock to return an empty array, this made the test pass. so this is a possible solution for you i think, though it doesn't mock or just forget rendering the view itself.

Unit Testing: Specific testing & Flow of Control

I am quite new to unit testing and testing in general. I am developing with phpUnit, but as my question is more general / a design question, the actual environment shouldn't be of too much importance.
I assume, that it is a good practice, to write your testcases as specific as possible. For example (the later the better):
assertNotEmpty($myObject); // myObject is not Null
assertInternalType('array', $myObject); // myObject is an array
assertGreaterThan(0, count($myObject)); // myObject actually has entries
If that is correct, here is my question:
Is it a accepted practice to write some flow control inside a testcase, if the state of the object one is testing against depends on external sources (i.e. DB) - or even in general?
Like:
if (myObject !== null) {
if (count(myObject) > 0) {
// assert some Business Logic
}
else {
// assert some different Business Logic
}
}
Is this kind of flow control inside a testcase admissible or is a "code smell" and should be circumvented? If it is ok, are there any tips or practices, which should be kept in mind here?
Paul's answer addresses test method scope and assertions, but one thing your question's code implied is that you would test A if the returned object had value X but test B if it had value Y. In other words, your test would expect multiple values and test different things based on what it actually got.
In general, you will be a happier tester if each of your tests has a single, known, correct value. You achieve this by using fixed, known test data, often by setting it up inside the test itself. Here are three common paths:
Fill a database with a set of fixed data used by all tests. This will evolve as you add more tests and functionality, and it can become cumbersome to keep it up-to-date as things move. If you have tests that modify the data, you either need to reset the data after each test or rollback the changes.
Create a streamlined data set for each test. During setUp() the test drops and recreates the database using its specific data set. It can make writing tests easier initially, but you still must update the datasets as the objects evolve. This can also make running the tests take longer.
Use mocks for your data access objects when not testing those DAOs directly. This allows you to specify in the test exactly what data should be returned and when. Since you're not testing the DAO code, it's okay to mock it out. This makes the tests run quickly and means you don't need to manage data sets. You still have to manage the mock data, however, and write the mocking code. There are many mocking frameworks depending on your preference, including PHPUnit's own built-in one.
It's okay to have SOME control flow within your testcases, but in general, understand that your unit tests will work out best if they are disjoint, that is, they each test for different things. The reason this works out well is that when your test cases fail, you can see precisely what the failure is from the testcase that failed, as opposed to needing to go deeper inside a larger test case to see what went wrong. The usual metric is a single assertion per unit test case. That said, there are exceptions to every rule, and that's certainly one of them; there's nothing necessarily wrong with having a couple of assertions in your test case, particularly when the setup / teardown of the test case scenario is particularly difficult. However, the real code smell you want to avoid is the situation where you have one "test" which tests all the code paths.

PHPUnit - test the validity of an SQL Query

I'm in the process of testing a factory class.
One of the methods must load the data in an array for an object that another method will instantiate.
That method contains the SQL query that holds a critical condition that must be tested. ( in this case only ask for the records that are "published". Ex.: WHERE published=1 ). That distinction in the SQL Query is the only detail that makes that method differ from another one, and I want to test the query execution behaviour.
Now, I can't really mock my PDO object and ask it to return a fixed result as I would not test the execution of the query by mySQL. That would make a useless test.
That leads me to think that I'll need to set up a static database with fixed test data inside it. Am I right on this or have I missed something?
Should I separate the test requiring the "test database" from the tests that are autonomous ?
I strongly agree on the part of not mocking out the PDO. At some point i want to make sure my queries work against a real database. While this might not be a unit test anymore, technically. For me it offers so much more to know that my code that handles data storage really works against the db.
What i tend to do is creating a sort of Data Access class for each Class that needs to talk to the DB and so separating out most of the business logic from the db access code.
That way i can mock out the data access when testing the classes and after that set up a "Test Database" for each "data access class" and see if those work.
#zerkms Answer (+1) already linked http://phpunit.de/manual/current/en/database.html and the only other resource i have found to be of value when it comes to DB-Testing is the Book Real-World Solutions for Developing High-Quality PHP Frameworks and Applications that has a big chapter covering this subject.
Should I separate test requiring the "test database" from the tests that are autonomous ?
Only if your testsuite gets really really big and you have runtime issues that force you to say "hitting even a testing database just takes to long for all my tests so i run those only on a continuous integration server and not while developing.
Yes, it is the common practice.
It is also the special methods for loading fixtures: http://phpunit.de/manual/current/en/database.html
What about second question: no, you should not separate them. Your tests should test the behaviour, not the details of implementation. Join test cases into test classes by logic.

How to create write-once properties?

I'm stuck with a general OOP problem, and can't find the right way to phrase my question.
I want to create a class that gives me an object which I can write to once, persist it to storage and then be unable to change the properties. (for example: invoice information - once written to storage, this should be immutable). Not all information is available immediately, during the lifecycle of the object, information is added.
What I'd like to avoid is having exceptions flying out of setters when trying to write, because it feels like you're offering a contract you don't intend to keep.
Here are some ideas I've considered so far:
Pass in any write-information in the constructor. Constructor throws exception if the data is already present.
Create multiple classes in an inheritance tree, with each class representing the entity at some stage of its lifecycle, with appropriate setters where needed. Add a colletive interface for all the read operations.
Silently discarding any inappropriate writes.
My thoughts on these:
1. Makes the constructor highly unstable, generally a bad idea.
2. Explosion of complexity, and doesn't solve the problem completely (you can call the setter twice in a row, within the same request)
3. Easy, but same problem as with the exceptions; it's all a big deception towards your clients.
(Just FYI: I'm working in PHP5 at the moment - although I suspect this to be a generic problem)
Interesting problem. I think your best choice was #1, but I'm not sure I'd do it in the constructor. That way the client code can choose what it wants to do with the exception (suppress them, handle them, pass them up to the caller, etc...). And if you don't like exceptions, you could move the writing to a write() method that returns true if the write was successful and false otherwise.

Categories