views:

211

answers:

1

I'm refactoring existing class to support Products import from CSV file.

 

Requirements:

1) during import products are identified by special product number.

2) product has category attribute. If such category exist - use its id, if not - create it first.

3) if product with some number already exists in DB - do an update of other fields in another case - create a new product.

 

Goal:

Make a real unit-test(no DB interaction) verifiing that categories creation/reuse works fine.

 

Correct me if I'm wrong:

1) I need to inject a list of existing product categories.

2) Loop through parsed products from CSV file and see whether category can be found in injected categories list or not.

3) What to return? Repository of aggregates(Should aggregate root be a product or product category?)

The problem is that we don't know what ID will new categories will obtain from DB.

Please give me some direction of how this problem can solved?


I'm new to the Repository pattern(and persistence-ignorant domain concept) and I'm using Mock testing in my daily coding.

+1  A: 

As far as I can tell, you need to ask about the previous existence of both products and categories. This hints at two different Repositories: a ProductRepository and a CategoryRepository.

Injecting a list of existing categories is one possible approach, but you would also need to inject a list of existing products.

Another alternative would be to inject both Repositories and simply ask them whether the product or category already exists. If you need other functionality provided by these Repositories, this may be a better option, since you already have the required dependencies.

You might also want to consider doing both to keep closer to the Single Responsibility Principle. One collaborator could be a service that constructs a new Product instance based on the parsed data and the existing categories and products. Another would be responsible for retrieving the existing data. Yet another class would implement the CSV parser.

All types would implement interfaces, so that you might have collaborators such as these:

public class CsvParser : IParser
public class DataRetriever : IDataRetriever
public class ProductCreator : IProductCreator

Your overall class would then be one that takes those three interfaces as dependencies and orchestrates their interaction.

This will allow you to unit test each in isolation using mocks for each dependency.

Mark Seemann