Search code examples
unit-testinggodatabase-testing

How would you unit test a method whose only purpose to make a database call?


I have method something like this:

func (alert *Alert) CreateAlert(db *mgo.Database) error {
    return db.C("alerts").Insert(&alert)
}

How should I unit test this? If I just call this method for uni test, then I will have to create test DB to which the call is made. I somehow feel that this would be part of integration test as we are making a call to DB.

If I mock the db object, then it will never test the actual implementation.

Should I test this at all? as the major goal for writing unit test if the data is inserted to DB or not, and such functionality are already tested in the library itself, in my case mgo library.

Please share your thoughts on what would be the best approach for unit testing the above scenario.


Solution

  • You would unit test it with a mock, so that the database isn't being called, but only your function is being tested.

    There are many different ways to mock a database, so I won't get into details, but a unit-test for such a small function will also be small. All you'll really be testing is that:

    1. the mock receives the expected data, in the expected format (i.e. does it receive the &alert value, passed to its Insert() method?)
    2. the mock's return value (an error) is returned to the caller of the function

    In particular, in a unit test of this function, you would not check that:

    • The SQL conforms to syntax expectations (your function doesn't control SQL, such a test would really be testing your data layer/ORM)
    • That the INSERT occurs as expected--this would be testing your database
    • That the caller of the function has appropriate database permissions (this is again testing your data layer and/or database)