TDD newb here. I know we "test the interface not the implementation", but might there be a case for having a "testing interface" of class X, using a Subclass Mock and protected methods, which could be a superset of the functional interface defined by the public methods of class X?
Say I have a class like this:
class IndexManager {
IndexManager( File file ){
super( file );
}
public void someFunctionalMethodUsedByOtherClasses(){
...
}
}
In my test class I go like this:
@RunWith(MockitoJUnitRunner.class)
public class IndexManagerTest {
...
class SubclassMockIndexManager extends IndexManager {
SubclassMockIndexManager( File file ){
super( file );
}
@Override
protected IndexWriterConfig createIndexWriterConfig( Analyzer analyser ){
return super.createIndexWriterConfig( analyser );
}
}
@Spy
@InjectMocks
SubclassMockIndexManager injectedSpySM_IndexMgr = new SubclassMockIndexManager(tempFile);
And make a method in it to test the "non-public interface" (AKA "testing interface"):
@Test
public void whenIndexIsMadeAnIndexWriterConfigShouldBeCreated() throws Exception {
injectedSpySM_IndexMgr.makeIndexForFile();
verify( injectedSpySM_IndexMgr ).createIndexWriterConfig( mock(Analyzer.class) );
}
In response, to turn red to green, I respond by modifying my app class as follows:
class IndexManager {
IndexManager( File file ){
super( file );
}
// added as part of normal red-green cycle TDD development
protected IndexWriterConfig createIndexWriterConfig( Analyzer analyser ){
return super.createIndexWriterConfig( analyser );
}
public void someFunctionalMethodUsedByOtherClasses(){
...
}
}
It's just that I'm puzzled why the TDD development cycle should necessarily be confined to testing methods which are exposed to all other classes...
Aucun commentaire:
Enregistrer un commentaire