When to write a mock object vs a Factory (FactoryGirl) - ruby-on-rails-4

I have a very large Rails code base, and we use lots of factories (FactoryGirl). The problem is, an instance of factory girl creates a database transaction so when we run our entire test suite, it takes a very long time. However, if we used Rspec mocks correctly then the tests would run lightning fast because mocks are feather light -- no DB transaction is required.
My question: when do you mock roles, entities or objects and when do you use a valid instance of an object? If someone could provide an example, that would be great.

I have learned to break down when to use FactoryGirl or active record instances in your tests. They should be used in your model tests and in your controller tests.
Model tests -- one must integrate with the database. If you are creating User tests that interact with user instances, then you will need User factories. However, if you are collaborating with other models, ones that are not the User model, then I would create doubles and stub methods for these collaborators.
One can also be generous using factories with Controller tests. Mainly because the controller is an exterior layer of your back end ecosystem. To test it, you will need to integrate with a lot of Rails and parts of your models. I find that it is ok to use factories here.
For the application logic -- service, domain, policy, plain old ruby objects -- you should tests each domain in isolation. For the unit or object under test, feel free to initialize it but create doubles, mocks and stubs for its collaborators.

Related

Unit Test in Rust Web Application

The most popular rust web frameworks, like actix_web, rocket, all seem to inject the database pool to the handler functions. That made me wonder how to do unit testing in those frameworks.
If you pass down the pool from the top to bottom, the only chance you'd have is to wrap the pool in a trait object and implement a mock sql pool yourself, returning the right objects when required. I assume most people won't write a sql engine to mock it.
Lazy static is the same story, if you access a global variable you cannot mock it for a specific method.
So what's left? Dyn Trait objects injected into the handler (service) which reference repositories (trait objects again). So when testing your service you can implement a mock repository returning the user you'd except in registration and it fails with "UsernameAlreadyExists" as expected.
Problem: Only repositories have a reference to the DB Pool. How to start a transaction? How to share the transaction down to other service methods? Always have two methods? Create_user and create_user_in_transaction?
You could also inject DAO dyn Traits, but there's the same problems as above.
I'm sure I'm missing something. Is pool in request handler really the way to go? How do you handle transactions? And unit tests WITHOUT hitting the DB but only your mock repository?
It really feels like it's untestable.

Testing process in Laravel application development

I'm following TDD technique in my new Laravel project. Thus I have a set of tests which cover my controllers, model classes, services, etc. Most of these tests are HTTP tests, so I stored them in the /tests/Feature directory. Additionally I have few unit tests, which cover quite specific methods, which are not (easily) reachable from the HTTP tests.
If I understand correctly, each HTTP test is a functional tests, because it covers a lot of classes included Controller. Should I in that situation separately create unit tests for each method in my project even if it is already covered by HTTP tests? If yes, what benefit can I take from it.
Thank you in advance for explanations.
The philosophy of creating unit tests is to test a small piece of your code, for example, if you have an API, so it only returns the list of 10 recent posts then I guess it's no need to create a unit test for that and it can be covered with writing the functional or HTTP tests. But let's assume you have an endpoint that the user uses that endpoint to upgrade his account from regular type to golden type so he/she can access more posts or videos. There will be definitely a lot of things going on in that endpoint, so yeah you need to write Unit tests in addition to functional tests. Also, one more thing is that when you write functional tests you should see it from the QA perspective, I can categorize it like this
Functional/Http/Feature => [Validation Checks, Response Checks=>[The endpoint throw an error in different situations or return success if all goes well]]
Unit => [Write the test for the small functions that they get called by that endpoint Or write the test for that endpoint and mock everything so you can get what you expect]
Integration => [Write tests for the third party APIs or database persistence or caching persistence that you are using in your application]
So if you have an endpoint and you are writing tests for that endpoint and your functional tests has covered some part of that endpoint logic then I guess it's not necessary to write more unit tests for it.

How to Unit Test a WebService call?

I have a standard web application, it contains a UI (which has an WebService API), which references a Business Layer which in turn references a SQL based DAL. These layers have a good coverage of unit tests which use mocking to replace their dependencies.
I also have an API library which allows users to access the WS via code (and handles a lot of the issues like credentials, urls etc). I want to write unit tests for my library.
Currently the only way I can do this is to write tests referencing the library and populate the database using the same mechanism I use to test the DAL. However this approach is clearly flawed as it doesn't test my API library classes - it tests the entire stack!
How can I insert a mock under the WS (which is in a different project)? I'm currently using MBUnit and MOQ to test.
EDIT: My unit tests currently test two things:
That the API is translating from WS objects to local objects I pass to the consumer correctly
That the fields of the transport objects were populated correctly
Your API really seems to be doing 2 things, so I'd place these responsibilities in 2 distinct modules and test them separately
A Translator module. Translates API calls into web service proxy calls and maps back responses from the web service to appropriate data structures defined in the API. To test it, use a mock of the Adapter module described below.
An Adapter / Proxy module whose job is to call the real web service. You can test it using integration tests. If the only way to do it is populate a database and exercise the full stack, you might want to move these tests out of your main test suite into a less frequent, long-running test suite.
Similar approaches are discussed here : http://blog.8thlight.com/eric-smith/2011/10/27/thats-not-yours.html and there http://nf2p.com/dot-net/mocking-web-service-proxies-using-the-adapter-pattern-to-allow-unit-testing/

Mocking and Repository / Service layers in C#

I am trying to write some unit tests for testing my service layer which I am doing well I think, the service layer as a dependency on a repository so am mocking a repository using RhinoMocks, so I am testing the Service layer "WITHOUT" hitting the database which is great.
Now I need to test my repository layer, this has a direct connection to a database so I have to test it don't i? I have no other option but to test it?
If I test another implementation of the Repository that doesn't hit the database then this is no testing my implementation.
I have managed to mock out all lower layers so anything that depended on code that takes a while to run ie. The repository, then I mocked this out. The result is that all my tests for layers below the repository complete fast and do not hit the database.
The problem is what do I now do with the repository. I have to test it but it has a dependency on a SQL database.
Well, the general answer goes like this. I would write unit tests that verifies the logic of the repository layer and break out the sql dependency in a new class and mock it in the tests of the repo. If the repository layer contains only a sql connection and no logic there is nothing to unit test in my opinion. Then you are more suitable with integration tests with the database connected.
Thus mocking code you don't own is a bad practice, I think best option for you is to test repositories via acceptance/integration tests
You certainly can test your repository layer without talking to a database. Most ADO.net classes are mockable, if you are careful about how you create them and you are careful to couple to interfaces instead of concretions. Unfortunately, ADO.net was created before mocking was a very popular practice, and it is still a bit of a pain to do.
The real question in my mind is whether you should try to mock them. The benefits of mocking are twofold: they run faster, and they force you to encapsulate more details about your database (making it easier to switch out db technologies, if you ever want to do it). The benefits of functional tests are that they also test your database layer (stored procedures, etc), they are arguably easier to write, and they are easier to maintain in the sense that if a db change is made, integration tests notice automatically, instead of you hunting the mocked out tests down.
I would say the "best" approach would be to test them both with moqs and with the real database, since this gives you the best of both worlds. However, it is quite costly of course.

Unit Testing in web applications that use databases

I am building a web application that uses the database for Users, Security/roles, and to store content.
It seems a little daunting to me to begin on the road of unit testing because I have to make sure my database has been initialized properly for my tests to run.
What are common practices to help in this regard?
i.e. while developing/testing, I might delete a user, but for my test to pass that user has to be in the database, along with his profile, security settings etc.
I know I can create a setup script, something to recreat the databas etc.
I don't want to end up spending my entire time maintaining my tests and ensuring my database is in sych
Or is that the cost of Unit Testing/TDD?
The solution is Mocking. Mocks "replace" the connection. The unit under test will "connect" to the Mock and executes its statement. The Mock returns normal resultsets o.s.e.
After the test, the mock can give you a list of all methods, that were called by the unit under test. Easymock.org
As the other said: DB connection aren't a unit test. So drop it and do it local with Mocking objects
It's not a unit test if you are testing more than one unit.
Usually you'll have one component (your page, or the business layer) talking to a data layer object that is responsible for actually connecting and querying the database. My recommendation is to develop a unit test for the first component, using dependency injection to pass in a mock version of the DataLayer (which acts on hardcoded data, or a List you pass in, etc). This way you are testing your higher level code in isolation from the other components.
Then you are free to develop other unit tests (and integration tests) for the data layer to ensure that it is handling it's job (writing to the database) correctly.
We use an in-memory database (hsqldb) for our unit tests. In the setup we populate it with test data and then before each test case we start a transaction and after each test case we roll it the transaction back. This means each testcase has a clean start of the db.
It sounds like you actually want functional/integration testing. For Web applications I recommend you look into Selenium or Canoo WebTest.
These are also great for automating tasks you do on the Web. I have a set-up suite and a tear-down suite that create business entities and testing users through the admin interface as well as tests for the customer-facing site.
Michael Feathers argues that tests that communicate with databases aren't unit tests by definition. The main reason for this is the point you bring up: unit tests should be simple and easy to run.
This isn't to say that you shouldn't test database code. But you don't want to consider them unit tests. Thus, if you do any database testing, you want to separate the tests from the rest of your unit tests.
Since I used Doctrine for my PHP database work, and since Doctrine has a query abstraction layer (called DQL), I can swap out back ends without having to worry too much about compatibility issues. So in this case for my unit tests I would just at the beginning of my tests load the schema and fixtures into a SQLlite db, test my models, and discard the SQLlite db at the end of testing.
This way I've tested my models and data access to make sure their queries are formed correctly.
Now testing the specific database instance to make sure the current schema is correct is a different story and IMHO probably doesn't belong in your Unit Tests, so much as it belongs in your deployment task list.
The cost of unit testing/TDD is that you have to alter your design so that you have a clean separation between the database and the domain layer, so that you can create a fake that will allow you to create tests that don't hit the database.
But that cleaner design is just the beginning of the cost. After that you have to create tests that both help you make the code work right the first time and alert you when anyone breaks something that used to work.
And after you have a good fundamental design with tests that protect your existing functionality, you'll find yourself cleaning up code to make it easier to work with, with confidence you aren't breaking things along the way.
And so on and so on... The costs of unit testing/TDD just keep piling up over time.
For Java, you may also want to look into dbunit. http://www.dbunit.org/