I am testing the functionality of a StoreManager class which has a dependency on DataBaseConfiguration class.
public class StoreManager {
private DataBaseConfiguration dbConfig;
public void Store(string name) {
dbConfig.Store(name);
}
//other methods here
}
The StoreManager class stores to a database and the only way I can test if this method works fine is to query from the database. I have another class in production which does that..
public class QueryManager {
private DataBaseConfiguration dbConfig;
public string Query(QueryExpression expr) {
//query logic
string name = "somename";
return name;
}}
Eventhough I am concerned with testing only my StoreManager class it looks to me like I need to use the QueryManager class to test the storedvalues.
So I have a basic test case like this one…
[TestFixture]
public class StoreManagerTest {
[TestFixtureSetup]
public void Setup() {
DatabaseConfiguration dbConfig = new DatabaseConfiguration(/*test database details*/);
StoreManager sm = new StoreManager(dbConfig);
QueryManager qm = new QueryManager(dbConfig);
}
[Test]
public void TestStore_ValidStore() {
sm.Store("testname");
string queryResult = qm.Query(new QueryExpression("query_expr"));
Assert.AreSame(queryResult, "testname");
}}
As you can see, apart from the ClassUnderTest (which is StoreManager), the QueryManager class also has a dependency on DatabaseConfig.
I don’t have a lot of logic inside the StoreManager class, it just delegates to the DataBaseConfig class to store (well actually there are some more classes involved in storing, its not the DataBaseConfig that actually stores the data.. but just for simplicity purpose, lets say so..)
I would like to know if there is a better way to handle this test without involving QueryManager at all?
Also is there a better way to inject the dependency on DataBaseConfiguration into the StoreManager class (considering that the DataBaseConfiguration class takes details about the connection string, etc., of the database to store the data into.. and I would like to pass in a test database rather than the production database connection string there).
To get the dependencies out of the way in testing the most common approach is to either use a handwritten stub or a mocking framework (i.e Moq or RhinoMocks).
Additionally you would have to enable users of the
StoreManagerclass to pass in theDataBaseConfigurationdependency, otherwise you cannot stub it out w/o changing the code. Constructor injection as you do right now is common practice and a clean way to do this (this becomes more convenient if you use an IOC container when you have lots of dependencies), also see here.If I understand you correctly, you just want to test that the
StoreManageractually stores the value you pass to it, you are interested in the behavior of theStoreManagerand its interactions with its dependencyDataBaseConfiguration– right now you do that by querying the data store itself for verification.Given that let’s go through a bare-bones example using RhinoMocks – the only thing I changed was define the
Storemethod in yourDataBaseConfigurationclass as virtual so RhinoMocks can override it.This test verifies that the Store method was called on your
DataBaseConfigurationclass w/o any other dependencies – it tests the behavior of yourStoreManagerclass. This test does not touch the DB nor does it affect any other classes.Edit:
I’m not sure I understand the concern about using a mocking framework in production code – the mocking framework is only used in your test projects, no reference to it or any code changes are required to the production code itself.
Using a handwritten stub you can do the same assertions “manually”: Define a test stub that stores how many times and with what value
Store()was called (again this requires theStoremethod to be declared virtual so it can be overridden):Now use this test stub in your test instead of the “real”
DataBaseConfiguration: