C # Design Questions

How to approach unit testing of private methods?

I have a class that loads Employee data into a database. Here is an example:

<P →
public class EmployeeFacade { public Employees EmployeeRepository = new Employees(); public TaxDatas TaxRepository = new TaxDatas(); public Accounts AccountRepository = new Accounts(); //and so on for about 20 more repositories etc. public bool LoadAllEmployeeData(Employee employee) { if (employee == null) throw new Exception("..."); bool exists = EmployeeRepository.FetchExisting(emps.Id); if (!exists) { EmployeeRepository.AddNew(); } try { EmployeeRepository.Id = employee.Id; EmployeeRepository.Name = employee.EmployeeDetails.PersonalDetails.Active.Names.FirstName; EmployeeRepository.SomeOtherAttribute; } catch() {} try { emps.Save(); } catch(){} try { LoadorUpdateTaxData(employee.TaxData); } catch() {} try { LoadorUpdateAccountData(employee.AccountData); } catch() {} ... etc. for about 20 more other employee objects } private bool LoadorUpdateTaxData(employeeId, TaxData taxData) { if (taxData == null) throw new Exception("..."); ...same format as above but using AccountRepository } private bool LoadorUpdateAccountData(employee.TaxData) { ...same format as above but using TaxRepository } } 

I am writing an application to create serialized objects (e.g. Employee above) and load data into a database.

I have a few design questions that I would like to express my views on:

A - I call this class "EmployeeFacade" because I (try?) To use a facade template. Is it good to use a template for the class name?

B - Is it good to name the specific objects of my DAL layer classes "Storage", for example. "EmployeeRepository"?

C - Is using repositories this way reasonable or should I create a method in the repository itself to take, say, Employee and then load the data from there, for example. EmployeeRepository.LoadAllEmployeeData (employee employee)? I am aiming for a cohesive class, but it will make the repository have knowledge about the Employee object, which may not be the best?

D - Is there a good way to avoid having to check if an object is null at the beginning of each method?

E - I have an EmployeeRepository, TaxRepository, AccountRepository declared as open for unit testing purposes. These are really private topics, but I should be able to replace them with stubs, so as not to write to my database (I overload the save () method to do nothing). Anyway, around this or should I expose them?

F - How can I test private methods - or is it done (something tells me about it)?

G- "emps.Name = employee.EmployeeDetails.PersonalDetails.Active.Names.FirstName;" this violates the Law of Demeter, but how can I adapt my objects to comply with the law?

+7
design c #
source share
6 answers

A - I would not call it XXXFacade, but something more meaningful (which actually means that you should call it XXXFacade)

B - I would call them XXXRepository

C. I really don’t understand your model here - you pass the Employee object and assign its values ​​to the equivalent values ​​in the EmployeeRepository. The repository should not contain data fields - each instance of the repository does not represent a row in the database. A repository is a way to get data from and from a database by working with sets of objects from a database (i.e., a repository is a table, Entities are strings). I would expect the repository object to have a Save method that takes an Employee object as a parameter and stores it in the database. Like the Load method, which takes an identifier and returns Employee:

 Employee myEmployee = repository.Load(112345); myEmployee.Name = "New Name"; repository.Save(myEmployee); 

The base class of the Repository does not need to know about the specific implementation of the Employee class, using generics and polymorphism. See Sh # rpArchitecture for a good example of this template.

D - yes, put this common logic in an abstract base class (repository)

E - do not make them public if they are to be closed. If you need the repository logic in your unit tests to simulate data fetching, follow a common interface, and then mock that interface in your tests. You do not need to verify that the repository is returning the correct data, since the data is in fact temporary and inconsistent. Better to fake it and test your behavior does what you expect from the predefined data from the mock repository.

F - Don't. Test behavior fails.

G. I do not think this problem exists if you research your architecture as described above.

+4
source share

How to approach unit testing of private methods?

You should not write tests for private methods.

The only possible way to create private methods is to refactor publicly available methods already tested .

+1
source share

A - I call this class "EmployeeFacade" because I (try?) To use a facade template. Is it good to name a template in the class name?

I do not think that testing private methods is a good idea; However, you can test "internal" classes that are similar to private ones in the sense that external assemblies will not have access to them by marking them as "Internal Visible" for your unit test project.

AssemblyInfo.cs - [assembly: InternalsVisibleTo("YourClass.Tests")]

B - Is it good to name the concrete entities of my DAL layer classes "Repositories", for example. "EmployeeRepository"?

I do this often, I don’t think that something is wrong with him.

C - uses repositories in this reasonably, or should I create a method in the repository itself, take, say, an Employee, and then download the data from there, for example, EmployeeRepository.LoadAllEmployeeData (Employee Employee Worker)? I am aiming for a cohesive class but it will require storage to know the Employee Object, which might not be the best?

If I do not understand correctly, I will keep them separate. I usually use the Repository classes as simple CRUD helpers; I would write a wrapper around the repository that provides you with the necessary functions.

D - Is there a good way to not need to check if the object is null at the beginning of each method?

If there is, I do not know, I would just use ArgumentNullException()

E - I have an EmployeeRepository, TaxRepository, AccountRepository declared public for unit testing purpose. These are really private but I need to be able to replace them with stubs so that they won't write to my database (I overload the save () method to do nothing). Anyway, around or should I expose them?

See my answer for A, designating them as Internal, and then set InternalsVisible for your unit test assembly. See Also MSDN .

F - How to check private methods - or is it done (something tells me about it)?

Usually I don’t test private methods, but I mark private classes that need to be tested as internal and use them in my test assembly.

+1
source share

A - I do not find it particularly bad to use the template name in the class name, although I honestly do not know how often this is done.

F - I think zerkms is right, you should probably make them publicly available, test them, and then make them private when satisfied. After privatizing them, you can still check out publicly available methods that use private methods to ensure that they continue.

As for your DAL and such, I would suggest exploring LINQ to SQL, available in .NET 3.0 and later. This is a good framework for handling the level of abstraction between your business logic and the database. Here are some links to check ...

A Quick Guide to LINQ to SQL in C # Part 1 of Scott Guthrie's Blog

Scott Guthrie has a lot to do with LINQ, if you're interested, you should learn more about your posts.

0
source share

A - IMO, yes. It will immediately remind you of the sample and help you understand the code, and this is perhaps one of the important methods of writing code, allowing others to understand your code.

B - I prefer the xxDAO (data access object) convention.

C - I prefer “service-oriented programming”, that is, a service that “knows” to save an employee, rather than a “repository object” that mixes “model” and “control”.

D - Aspect is possible, but I do not recommend it.

E - You can create an interface for those who are classified and enter them from the "outside" using installers (as spring does), or get them from a kind of factory, so it will be easy for you to replace the classes with a layout and leave the members "private".

F - I think that these methods should be extracted from the "bootloader" and be self-service. IMO, you should abstract the "employee data" objects (especially if you got 20 of them :-)). and write a simple service that knows to load an "employee data object" of any type.

Hope I helped
Shay

0
source share
  • Your naming convention looks ok.

  • By invoking specific repositories, you are tightly connecting the system. Pass them repo objects in the constructor. Or use a DI / IOC container.

  • If the repository returns the employee, he will know about it. You might want the repo to recognize the contract for the employee class.

  • If you get a null value for something, you have to make sure the provider code is not sending empty values.

  • You can achieve this by doing the correct dependency injection and using interfaces.

  • Standard unit testing modules will not give you this, you will need something like Moles . Sample is shown on this post.

  • Use inheritance more than composition if you can. But if the object model requires this, then you are helpless, in my opinion.

0
source share

All Articles