Showing posts with label questions. Show all posts
Showing posts with label questions. Show all posts

Saturday, December 12, 2009

Saturday question: testing in .NET

A reader wrote to me asking resources for learning how to implement Test-Driven Development in an .NET environment:
Please pardon me for my unsolicited email, but I saw your blog and I believe that you are one of the best in the software community. My name is [omissis], and I'm a C#/ASP.NET programmer from the Philippines, but I really want to learn and understand Unit Testing and TDD the right way. I didn't take Computer Science or a similar course in college. I really want to learn software design and development, on how to develop an application from ground-up using TDD. I hope you can give me advices, since I'm not able to afford a good book.
I am no particular expert in C# since I mostly work in php. As you may know, I have written a free CreativeCommons-licensed ebook on php applications testing.
For the .Net case, if you are a beginner, there is a book I reviewed which is a good starting point: The Art Of Unit Testing, which has lots of .NET examples included.
It costs $26 on Amazon now, which you can consider an investment since the knowledge contained could make you earn more in the future. It is a very complete book.
You can also obtain the book for free via other means, such as public libraries. I personally use a lot my university's library to look for information in technical books like Design Patterns when I am not going to buy a copy at the moment, as they are not diffused in normal libraries. You already pay for libraries with your taxes so you'd better take advantage of them.

Once you have the basis, the best way to improve is practicing... Someone said that a developer becomes proficient in unit testing after having written 1500 tests.
For general advice, you may also follow this blog and the Google Testing one, although they are focused on technologies different from .NET.
The principles of testable and decoupled design are the same in all object-oriented languages, and the distinction between C# and php resides in how and when an application object graph is created.
I hope you can find this references useful to start your journey.

Saturday, November 28, 2009

Saturday question: mixing Repository and Active Record

Saturday is becoming the 'questions day of week', since it is not the first time that after a week of work some readers email me to carry on the discussion on design and testability, two topics that are stressed in my blog posts. :)
This week, Fedyashev wrote to me about mixing architectural patterns in a single application:
I really like these Active record and Repository patterns.
The drawback of Repository pattern is its cost(takes more time then
Active record). Benefit is higher abstraction which really helps on
complicated business logic.
The drawback of Active record is that lower testability(db interaction
is required) and harder in handling complicated domain logic.
Is it acceptable to take the best of these two patterns to be used in
the same application?
I was thinking about using Active record for simple CRUDs and Repository
for complicated domain objects.
The idea behind this intention is to keep cost of code lower but still
have a good code.
What would you recommend?
There are cases in which Active Record would be an acceptable pattern. Since the drawback of Active Record is little testability, the primary scenario for its application is when there is nothing to test. Some applications are data intensive and require only to move information back and forth from the database.
CRUD screens, as you suggest, often have little logic and can take advantage of active records. But we should evaluate case by case, since it is very easy for logic to leak into Active Record instances, and logic should be thoroughly tested.
For example, logic is present in managing validation of entities upon insertion and editing: a classical situation is searching for already existent nicks upon user registration. A Repository is capable of performing validation using external resources as they can be injected at construction or passed as a method parameter, while an Active Record probably not (and it will be more complex to test this validation).

Another problem I see in mixing up these patterns is the different libraries requirements. Typically, we want repositories to aggregate an instance of a lower-layer framework that encapsulates Sql queries or whatever storage we are using (Hibernate or Doctrine 2), while Active Records are subclasses of other frameworks abstract base classes (Zend_Db or Doctrine 1).
The paradoxical result is that implementing both patterns leads to use two different version of Doctrine at the same time, which I do not recommend for maintenance reasons and code clarity.
A solution would be keep the implementations in two separate BoundedContext, which are different domain models that can communicate, for instance using the same underlying relational database. Though, BoundedContext is a DDD term and suppose that you work with persistent-ignorant models in both contexts.

However, the real choice is not between Active Record and Repository but between Active Record and Data Mapper (persistence-ignorant domain model). It seems for instance that Doctrine 2 provides a default repository class you can tweak later, although it has default methods only for retrieving entities and not to insert them (I think the insertion can be managed with events). It's not really difficult to change your approach from:
$user = new User();
$user->nick = 'John Doe';
$user->save();
to:
$user = new User();
$user->nick = 'John Doe';
$em->save($user);
when what you gain is freedom from activating a mysql daemon to test the User class, without using Repositories. Repositories may come into play later, when and where you want a finer control on the bridge with the database.

Thursday, November 19, 2009

More questions on controllers testing

Sune wrote to me yesterday with some questions about testing Zend Framework controllers and proper dependency injection, which to me is a fundamental practice in object-oriented programming. I have already responded to similar mails in the past and this seems to be an hot topic nowadays, so as always I think other readers can benefit from this discussion and I'm sharing it here.
Because of you I am trying to move my software to use factories and dependency injection, also removing
singletons and Zend_Registry usage in controllers. But I am a bit confused, what is the right way to do this.
My plan is to bootstrap the main factory in the bootstrapper, and then use
$this->getInvokeArg('bootstrap')->getResource('factory') in controllers. Is this good practice?
Summarizing, the best thing would be creating the controller by yourself (or having its creation configured someway), but it can be an overkill to set up a similar approach on a Zend Framework application, since it requires a third-party DI container and controllers should always be thin.
Thin controllers means we probably want only to perform integration testing on them with Zend_Test, and not real unit testing as there is not much logic to exercise.
Since we cannot create in the bootstrap all the collaborators that could be possibly needed (we want to lazy-load collaborators that may not be referenced), your approach is similar to a Guice provider and I think it is very valid. In integration testing you should then use a different factory or configure this one to provide some fake components when the real ones are not applicable. For instance, a mailing service object ca be replaced with a fake implementation that records all the sent mail and lets you assert on them.
And in conjunction with that. Would it be good practice to inject a Zend_Config object into the factory?
Some models requires options from the config file, smtp username etc. and the factory would need those information to create the models.
Of course. It's up to you how to organize the config object, and you can and should change part of it in the testing environment. The power of DI containers is that during configuration you can specify not only scalars like database connection strings, but also different classes and implementation for the collaborators you inject.

Saturday, November 07, 2009

Questions on controllers testing

A different kind of controllerDavid Weinraub has written to me asking some basic questions about my last post on dropping unit testing for controllers. I am glad to write a less technically advanced post to answer these questions for the readers that experience difficult in following the discussion in the previous post. I guess it can be helpful for other developers that have just started exploring the possibilities of good object-oriented programming.
Let's start with the questions.
On your recent post How to not test controllers, you have the following code in a controller:
$repository = $this->application->factory->getUserRepository();
Was this what you meant in our previous discussion by using a single app-wide factory for creating your service objects? The factory with approx 100 calls to "new"?
In my opinion pure factories should have nearly no logic: they only create objects and their responsibility resides here. Though, in my approach only the controllers know that a factory exists.
So you create this $factory at some early phase, bootstrap I guess, and then "store" it as an attribute on the $application object? Presumably the $application object is always accessible wherever I am in the app, so if I need some service, either to use directly or to pass as a collaborator to some other service (like a repository or a mailer), I can get it using code like the above.
The container which provides the factory is not important, but in this case is the Zend Framework bootstrap object or a Zend_Application instance, the only things that the infrastructure allows us to inject into controllers. It would be great, alternatively, to inject only necessary services in the controller, having also the controller object created by the factory (but it's not supported out of the box in zd).
Note that for easiness of decoupling and testing, this choice is bad: every time we break the Law of Demeter in a class its tests will increase in size and complexity. Normally I want to avoid these violations but since I decided to treat the controllers only as wiring code and not to unit test them it's not a problem. All my business logic is kept in the underlying domain layer if it is domain related or in action and view helpers if it is focused on data formats like html and json, or other cross-cutting concerns; these classes are then extensively tested and writed via TDD. I test controllers only in integration, and their responsibility is to act as a dumb bridge between requests/view variables and the Domain Model. Controllers are only very simple mediators in my applications: I would unit test them if I do not have to import third-party libraries to inject their collaborators, because their Api will improve.
Perhaps the factory itself calls it's own methods when it needs to create more complicated services using collaborator services?
I do this all the time. It's stupid to not reuse code :) However, it is usually simpler to expose only the narrow set of end-user services: for instance my Reflector, which gathers domain classes metadata, is used only by other services and so it is created in a protected method. Only the services which are requested directly by controllers earn a public method.
Does this factory maintain an internal registry of the objects it has created, so that subsequent calls to the factory do not produce duplicates of the objects? Or alternatively, is it is "dumb" factory, so that each call to, say, getUserRepository() creates a new one. I can't imagine you allow your factory to make duplicates like that.
If you want, you can cache them in the factory field references, and even unit test the factory by requesting the same service twice and executing assertSame() on the objects returned. In php it's not very useful: how many times a service is requested two times from the factory, by the same controller? It makes a lot of sense in Java where objects are not garbage-collected between http requests and can thus be shared. It is also necessary in php mainly when a collaborator must be shared between different services.
The nice caveat is that if you implement consistently this caching also the smaller factories (which create objects with shorter lifetimes like View Helpers) will be cached as they are instanced once in the main factory and then shared. This is true with every level of nested factories you reach and, without using singletons, you will never need to duplicate an object when not needed.

I guess I have clarifyied why I am abandoning unit testing for controllers and making them break the Law of Demeter, without feeling remorse or renouncing to a good design. Feel free to post comments to continue the discussion.
The image at the top is a photograph of a SNES controller. This is a pun and not the controller we are talking about.

Featured post

A map metaphor for architectural diagrams

It is a (two-dimension) representation of a pipe. The map is not the territory , but in software engineering terms they are models of it....

Popular posts