Mahesh Velaga
Mahesh Velaga

Reputation: 21971

How do I test a method which has database queries to update data?

I have a method like the following:

public void ImportDataCommand()
{
    // some data validation logic here

    if (some_criteria_is_true)
    {
        // Call to a method which uses sql queries to update some records
        UpdateRecords();
    }
    else
    {
        // Call to a method which uses sql queries to delete some records
        DeleteRecords();
    }
}

Update

I am not interested in mocking the data source here. I want to make sure if my SQL queries are correct and are doing the right updates. Sorry for the confusion, if you thought, I wanted to test my validation logic as opposed to my data update logic (SQL).

I do have experience with mocking frameworks and I did use them successfully to write unit tests for my normal application logic.

Upvotes: 2

Views: 2751

Answers (4)

blank
blank

Reputation: 18180

Your problem starts with the phrase 'as well as'.

Don't have validation and data access in the same class - delegate the data access to another class and inject it - this way you can mock out the data source when testing your validation.

class Bar {
private DataAccessService service

public void Foo()
{
    // some data validation logic here

    if (some_criteria_is_true)
    {
        // Call to a method which uses sql queries to update some records
        service.updateBarRecords();
    }
    else
    {
        // Call to a method which uses sql queries to delete some records
        service.deleteBarRecords();
    }
}

}

You can then use a mocking framework to test that the correct service methods are called.

Upvotes: 3

mamoo
mamoo

Reputation: 8166

IMHO you should address this issues in your code:

  1. Foo is not unit-testeable, because it doesn't return anything
  2. You're coupling data access to your app logic, that makes different layers too tied together to actually unit test them
  3. Probably a method in which you call update and delete depending on a certain condition is a smell... shouldn't be better to have two different behaviors?

Since the naming of Foo is not self explanatory there's no much else, but if you could detail the context of the method we could add more remarks.

Upvotes: 0

Zenwalker
Zenwalker

Reputation: 1919

When you do unit testing, you concentrate particularly only on that unit i.e a method here. So when you write a test case, you mock the other methods which you usually call via a dependency injection (if its a API call or some thing). Other wise, what that method does you just guess and write the test case.

So in your code case, you are suppose to write a test cases for Foo(), UpdateBarRecords() and DeleteBarRecords() seperately.

Ignore all the method calls (unit testing it) and concentrate on the core logic code you have written in that method which you are concentrating for unit testing.

Upvotes: 0

Davide Piras
Davide Piras

Reputation: 44595

This depends on the whole architecture of your application and the IT/DB infrastructure of the company as well as data policies you could be enforced to follow by DBAs, in mid size or big companies.

in the past people used to have an instance of SQLite for unit tests, or you can have the same technology for example SQL Server but have unit tests to connect to development or QA database servers, surely not production.

One thing I did in the past was to have a transaction around the command executions and rollback the transaction at the end, in the unit tests, so nothing is ever persisted on the DEV/QA databases but the testing of command execution is performed anyway.

Upvotes: 0

Related Questions