I have the below GetDocuments() method which is public, and i want to unit test the ReadData() method which is private. I am using Moq framework. what is the approach i have to take to test ReadData() using the GetDocuments() public method.
public IEnumerable<DocContent> GetDocuments(){
sql = "testing"
return sqlCommand.ExecuteReader<List<DocContent>>(sql, null,
(reader) => {
while (reader.Read()) {
contentDataList.Add(ReadData(reader));
}
return contentDataList;
});
}
private DocContent ReadData(IDataReader reader) {
return new DocContent() {
Key = (string)reader["key"],
Type = (string)reader["type"],
ValueAsXmlDoc = ToXmlDocument((string)reader["value"])
};
}
CodePudding user response:
You're approaching unit testing this logic incorrectly - the public method signature is IEnumerable<DocContent> GetDocuments
- and that's what should be tested. Unit testing does not approach testing specific internals of the class under test; only the public surfaces.
In your instance, it sounds like what you're doing is testing the sql response to translation logic - and you can actually do that entirely in an integration test.
You can construct a MDF file which is an in memory database of functionality using SQL Server syntax. You can easily add one from the Visual Studio Add Item menu.
You can populate that MDF file with content all with the SQL editor in Visual Studio.
At unit testing time, set your
SqlConnection
andSqlCommand
to use the in memory MDF file. The connection string is like so:Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename={DatabasePath};Database={databaseName};Integrated Security=True;MultipleActiveResultSets=True;Connection Timeout={ConnectionTimeout}
You can then invoke your public method signature and receive back fully hydrated objects that ran through your entire method chain, testing the
DocContent
objects you received back. It fully tests the integration between your code, the SQL driver, the SQL command you need to execute, and the translation of the objects coming back.
CodePudding user response:
One way you could do it is to move the ReadData
method to the actual DocContent
class and make it public (or use a constructor) - or have a separate class DocContentFactory
with a public ReadData
method and then unit test and use that.