Unit Testing Destructive Methods - unit-testing

When doing unit tests on models, and database-altering methods/functions, what is the best methodology or mindset for unit testing? For instance, a "publish" function in a model has no test-able behaviors except for pass/fail, and in the case of passing, it modifies the database. Best practice or approach?
Current thoughts would be to create a mirror of the current database before testing, and just change the database selection in my unit test file. Thank you for your suggestions.

If you want to do unit test (=test in isolation):
the business logic would execute against a fake database (Repository mock)
the test checks if business logic has really called repository-delete method.
If you want an integration test with the business logic and the database you can
open a database transaction
add data to database via sql
execute the business logic that destroys the data just added
verify that data is not in database any more (via sql)
rollback the database transaction.
Update:
If you are using .NET you should have a look at ndbunit for java dbunit

Use xtunit if you are on .net. This will wrap your test in a transaction and roll it back when it's done.

Don't mirror the database... stub it. If you are testing against a database, You are not unittesting.

Related

When to write a mock object vs a Factory (FactoryGirl)

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.

Django Unit test

i have two servers,one working as api and another used to retrieve the data from api(webui).If i perform any unit tests for views in webui,it is creating objects in api.How to delete the objects in api after the testing is complete?Can you suggest any ways to deal with this issue?
If you are testing then you should have a separate system that does not impact upon anything that is being used in production.
You could use mocks to create the intended responses from the api for example.

How to implement BDD on very complex business rules?

I am learning the art of Unit Testing and BDD and in my company there is no one who follows this approach. I try a lot to learn it by myself but get stuck somewhere and give up after trying for a few days. After some time I get inspiration again from someone and try to learn to swim in these waters again.
I have recently developed a Windows Service that started out small but ended up a big ball of messy business rules. Here is a brief overview of what the service does.
Log to database “Service starting…”
Get Data From DB that needs to be posted to another web service
If there is no data to post Log to database “No data to process…”
and exit service
If data contains duplicate values Log to database “Duplicate data
found, this record will be skipped.”
Update the status of the record for which duplicate data was found
to something e.g. 302
If the data is null, Log to database “Record contains null value and cannot be processed.”
Update the status of the record appropriately e.g. 310
If the database is unavailable or down due to some reason, Log in a file “Database is down…”
If the service is down where we have to post the data log to database “Receiver service is down.”
Log to the database “Exiting service…”
So my service basically retrieves some data from the Database, creates JSON request from it and post it to another service.
It also parses the response from that service and logs if the data was posted successfully or not. I have just entered some of the business rules that are currently implemented in the service to give you an idea of what lies under the hood. I am learning BDD and unit testing and would really love to know how an expert will write test cases that test these complex business rules?
From my understanding BDD does not need to focus internally on how the service is written, instead it will test scenarios that service should fulfill For example
When executing the windows service with duplicate data
It should log to database “Duplicate data found, this record will be
skipped.”
It should update the status of the record to 302
I can write multiple scenarios that test some functionality of the service. Is this the right approach or should I right very large sets of scenarios that test each business rule in every test?
Secondly as the service is communicating with the DB as well as a web service, how can I test the HttpRequest and HttpResponse that is sent and received by the service?
Finally how do I actually test something as complex as the business rules I have written above, If I simple assert that the service called some specific method of some class is that enough? How do we know that by simply calling some method it will perform the right task?
A few simple thoughts to help keep it in perspective:
You say learning...
Keep that in mind and don't get hung up on what is perfect, right, or proper. You're learning, feel free to make mistakes and know that you'll improve as you go. Keep at it, keep practicing, you'll get better and it will feel more natural the more you do and the more you think about it.
BDD tests behaviors.
You use this to say the system should behave in a specific way, and that implies that it must be the system. You may still stub in a couple dummy services, on occasion (like a fake credit-card processing service) but for the most part, you want this to prove the system works as needed. Think of them as more of integration tests.
Your BDD tests should drive your Unit Tests.
Write the BDD test to fail, and then let that dictate what unit tests should be written in order to get your system to behave as you expect. This essentially means that each BDD test of yours will introduce a set of Unit Tests as well.
In summary, let BDD drive TDD
and you'll have the right balance of tests. The starting point is with your first BDD test.
And in your scenario, if your system is supposed to alert the user that they are attempting to add a duplicate, that's a valid test.
The annoying thing with testing Http Requests and Responses are that you end up doing string comparisons, but that is doable. The BDD tests should just care that the system responded as you expect.
The unit tests should isolate in respect to what you are doing, so you would have unit tests inside your web service to make sure it responds correctly, but you would not have a unit test on the outside that calls the web service; extract it out instead.
It all can become pretty philosophical, and that probably gets into what makes a good unit test versus what makes a good behavioral test, but hopefully this helps you get started down the road.

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/