J. Doe
J. Doe

Reputation: 129

How to mock a database for SQLiteDataReader.GetString?

I have an extension method for SQLiteDataReader that casts the data gotten from the GetString method.

public static DateTime GetDateTime(this SQLiteDataReader reader, int columnNumber, string format)
{
    string date = reader.GetString(columnNumber);
    DateTime dateTime = DateTime.ParseExact(date, format, null);

    return dateTime;
}

In order to unit test it I suppose I'd need to mock a database or, somehow, replace the GetString method.

Should I use an example database for my unit tests, mock it or mock the GetString altogether?

Upvotes: 1

Views: 163

Answers (1)

Nkosi
Nkosi

Reputation: 247521

The main problem here is that SQLiteDataReader has an internal constructor, which would make trying to mock it rather difficult. That leaves trying to perform an integration test with an actual connection, command and reader, which is not very isolated.

If however the extension method was refactored to depend on the abstraction like DbDataReader

public static DateTime GetDateTime(this DbDataReader reader, int columnNumber, string format) {
    string date = reader.GetString(columnNumber);
    DateTime dateTime = DateTime.ParseExact(date, format, null);
    return dateTime;
}

It would allow for the extension method to be more easily tested using a mock reader

[TestMethod]
public void Should_GetDateTime_Given_Format() {
    //Arrange - using Moq
    string expected = "2020-02-22";
    string format = "yyyy-MM-dd";
    int columnNumber = 0;
    var target = Mock.Of<DbDataReader>(_ => _.GetString(columnNumber) == expected);

    //Act
    var actual = target.GetDateTime(columnNumber, format);

    //Assert - using FluentAssertions
    actual.ToString(format).Should().Be(expected);
}

And also means that the extension method is reusable on other derived DbDataReader and not just SQLiteDataReader

Upvotes: 1

Related Questions