I would say that it is from top to bottom. Let's say I had a single PDF in which there were 4 different documents, and I wrote software to separate them into 4 separate documents instead of a single document, the first test I would probably write is the following:
// Note: Keeping this very abstract
@Test
public void splitsDocumentsAccordingToDocumentType () {
List docs = new DocumentProcessor (). Split (new SinglePdfWithFourDocs ());
assertEquals (4, docs ());
...
}
I would consider the DocumentProcessor.split() method, which would look like "A" in your example. Now I could implement the whole algorithm in a single split method and skip tests. I don’t even need a “B” or “C”? Knowing that you are a good developer, and you are compressed at the thought of this method of 1500 lines, you will begin to look for ways to rebuild your code to a more suitable design. Perhaps you see that two additional objects (duties) can be divided into this code:
1) Parsing the contents of a file to search for individual documents, and 2) Reading and writing a document from the file system
First, let No. 1 do it. Use a couple of Extract Method refactoring to localize the code associated with the content parsing, and then Extract the Class refactoring by pulling these methods into a class with the name, say DocumentParser . It could be similar to "B" in your example. If you want, you can transfer the tests related to parsing a document from your DocumentProcessorTest to the new DocumentParserTest and run a mock or stub DocumentParser in DocumentProcessorTest .
For # 2, this is pretty much foam, rinse, repeat, and you get something like the DocumentSerializer class, AKA "C". You can mock this also in your DocumentProcessorTest , and now you don’t have file I / O, and it has a component-driven test that has two additional collaborators, without having to design your entire class (using separate methods). Please note that we used the “outside” approach, which really allows refactoring.
thanks
source share