How to unit test a spreadsheet parser?
I have a DeliveryScheduleParser
class that reads in a spreadsheet and parses it into a number of objects that all end up in a client object that is returned by the getClient()
method in the DeliveryScheduleParser
class.
public class DeliveryScheduleParser {
private final HashMap<String, Integer> _headerColumnNumbers;
private final File _file;
private HSSFSheet sheet;
private Client client;
public DeliveryScheduleParser(File file) {
this._file = file;
sheet = getSheet(_file);
_headerColumnNumbers = getHeaderMap(sheet);
parseSheet();
}
public Client getClient(){
return client;
}
// Other private methods here
}
开发者_Go百科
The parseSheet()
method inside this class basically does all the work and only calls some static Sanitizer methods that are separately unit tested.
My question is basically what would be the best way to make sure that the client object is properly filled with the right objects, and that those objects are in turn also filled with the right objects (there are a lot of ArrayLists
nested within other ArrayLists
).
I'd also like to run the unit test against spreadsheets with different data to ensure that all the parsing is correct.
I guess this scenario composes of two suits of tests.
- You have to have an Interface called Client. You should mock it and see if your DeliveryScheduleParser interacts with it properly. So first mock your Client and test your DeliveryScheduleParser.
- Now define your expectations from a Client and write down your tests one by one. Then implement your class that implements Client interface (so a ClientImpl).
For mocking you may like to use Mockito or any mocking framework for ease.
So basically to be able to "make sure that the client object is properly filled with the right objects" you have to test your Client
but not immediately DeliveryScheduleParser
. Actually your DeliveryScheduleParser
should be a collaborator and interact with the Client
.
Then you may like to decompose this implementation in a similar fashion since it sounds like objects here are quite coupled.
For ArrayList
interactions you may like to use List
interface and mock it.
Testing against different spreadsheets is an integration test. There again you can mock your file provider (here it is not clear) in a way that you can provide different spreadsheets in each test. You can just add those spreedsheets to resources under test folder and can use reource loader to load test sheets. I would also separate those tests from the unit tests for speed.
I'd like to be more specific but hope it helps...
Since your class seems to parsing real files into the object world, I'd recommend writing integration tests - tests that exercise your class with real files. The unit tests for types that use the parser can rely on a role/interface (and mock it).
You can also the equivalent of data-driven / parameterized tests to run the same test against different inputs (in this case files)
Ideally the parsing responsibility should reside in one type/class. It should take in an input and produce another type (a data structure/object) as output.
精彩评论