Symfony2 Functional Testing: Is a database required or not?

490 views Asked by At

I have to write functional tests for a controller that registers a user in the application.

The controller has two methods (and routes):

  • registrationAction (route=registration)
  • endAction (route=registration/end)

Now I would like to write functional tests for those two methods.

My question is: as the controller creates and persists a new user in the database, should have I to use a test database? Is the mocking of entity manager a solution? And how can I test that the user is correctly created in the database?

The Symfony's documentation, speaking about functional testing of forms, don't mention database, but generally the filling of the form and the submit of it. But if i try to do the same thing in my functional tests, they return errors (and I think they are right: there is no database where to save submitted data!).

So, I think I should use a database for functional tests, but I don't understand why:

  1. Symfony's documentation doen't mention the database
  2. Someone suggests to use mocks of the Entity Manager.

I'm a bit confused: should have I to use a database or not?

1

There are 1 answers

2
Tomasz Madeyski On BEST ANSWER

Answer to this question in not simple yes/no, you can do it in both ways, both have its advantages and disadvantages.

1. With test database

You mention that you need to write controller test. Testing controller is testing of almost top layer of your application flow. Controller depends on many class implementations which you would need to mock if you would like to test your controllers logic with isolation. If your controller has it's dependencies injected into contructor using service container I would possibly think of mocking but if it extends Symfony's Controller I would use test database mocking everything in this case would be harsh.

2. Without database

In this case you need to mock your entity manager and this is possible. However in your case I would think of refactoring. Move logic outside your controller to some UserManager or similar class. Register this class as a service and inject all required dependencies. Think of injecting repository instead of whole EntityManager as described here. Now, because your code is more single responsible it's easier to write tests and it's easier to mock all of your dependencies.

Conclusion: do refactoring, move your logic outside of controller, write test for single responsible class by injecting mocks of dependencies into it.