问题
For example:
public interface IMessageService
{
void ProcessMessages(IEnumerable<Message> messages);
}
Implemented the interface:
public class MessageService : IMessageService
{
public void ProcessMessages(IEnumerable<Message> messages)
{
// whatever
}
}
Then realized that ProcessMessages should be broken down a little bit to handle different parts of the message:
public class MessageService : IMessageService
{
public void ProcessMessages(IEnumerable<Message> messages)
{
foreach (var msg in messages)
{
ProcessCustomer(msg.Customer);
}
}
private bool ProcessCustomer(Customer c)
{
}
}
Next, wanted to unit test ProcessCustomer so made ProcessCustomer public and at this point the method is not accessible without a cast, so what's the point?.
回答1:
Consider following. You go to the pizza shop and you want to test their pepperoni pizza. Do you want to test how sausage slicer works? No. You want to see five pieces of pepperoni sausage on your pizza - that is requirements for pizza shop. Actually it even does not matter whether sausage was cut manually or with slicer. You should only verify that all requirements are implemented correctly.
Same with your class - it's requirement is processing messages. It does not matter how processing of messages is implemented - whether it calls some helper method inside, or not. So, my advise is always same - do not test private methods - they are not required to exist, and their existence should not be tested.
回答2:
You should make the ProcessCustomer method internal and then add an InternalsVisibleTo attribute in your AssemblyInfo.cs file so that your unit test assembly can access the method (but not any other assemblies). Further, you should make the MessageService class internal as well so no outside assemblies can access it. This way, only public part of your design is the interface.
Alternatively, instead of mocking around with the internal access modifier, I've at times used an approach similar to this:
http://exposedobject.codeplex.com/
回答3:
The ProcessCustomer method is not part of the interface so you would need to cast to the object type before being able to use it.
If you are accessing this object type through the interface you would need to cast to the MessageService type object first.
回答4:
To answer the question why method in interface is not public:
Interface by design is a contract and implicitly made public. This is by design in the language. So there is no need to use the keyword public.
来源:https://stackoverflow.com/questions/21891918/whats-the-point-to-have-public-method-in-class-but-not-in-interface