C# 什么';在类中而不是在接口中使用公共方法有什么意义?

C# 什么';在类中而不是在接口中使用公共方法有什么意义?,c#,unit-testing,interface,C#,Unit Testing,Interface,例如: public interface IMessageService { void ProcessMessages(IEnumerable<Message> messages); } 公共接口IMessageService { 无效处理消息(IEnumerable消息); } 实现了以下接口: public class MessageService : IMessageService { public void ProcessMessages(IEnumera

例如:

public interface IMessageService
{
   void ProcessMessages(IEnumerable<Message> messages);
}
公共接口IMessageService
{
无效处理消息(IEnumerable消息);
}
实现了以下接口:

public class MessageService : IMessageService
{
     public void ProcessMessages(IEnumerable<Message> messages)
     {
        // whatever
     }
}
公共类MessageService:IMessageService
{
公共void进程消息(IEnumerable消息)
{
//随便
}
}
然后意识到ProcessMessages应该被分解一点以处理消息的不同部分:

public class MessageService : IMessageService
{
     public void ProcessMessages(IEnumerable<Message> messages)
     {
       foreach (var msg in messages)
       {
          ProcessCustomer(msg.Customer);
       }
     }

     private bool ProcessCustomer(Customer c)
     {

     }
}
公共类MessageService:IMessageService
{
公共void进程消息(IEnumerable消息)
{
foreach(消息中的var msg)
{
ProcessCustomer(msg.Customer);
}
}
私有布尔过程客户(客户c)
{
}
}

接下来,我们想对
ProcessCustomer
进行单元测试,这样做
ProcessCustomer
public
,此时,如果没有强制转换,就无法访问该方法,那么重点是什么呢?

您应该将ProcessCustomer方法设置为内部,然后在AssemblyInfo.cs文件中添加一个
InternalsVisibleTo
属性,以便单元测试程序集可以访问该方法(但不能访问任何其他程序集)。此外,还应将MessageService类设置为内部类,以便外部程序集无法访问它。这样,设计的唯一公共部分就是界面

或者,与使用内部访问修饰符进行模拟不同,我有时使用类似的方法:


您应该将ProcessCustomer方法设置为内部,然后在AssemblyInfo.cs文件中添加一个
InternalsVisibleTo
属性,以便您的单元测试程序集可以访问该方法(但不能访问任何其他程序集)。此外,还应将MessageService类设置为内部类,以便外部程序集无法访问它。这样,设计的唯一公共部分就是界面

或者,与使用内部访问修饰符进行模拟不同,我有时使用类似的方法:


ProcessCustomer方法不是接口的一部分,因此您需要转换为对象类型才能使用它


如果您通过接口访问此对象类型,则需要先转换为
MessageService
type对象。

接口中不包含
ProcessCustomer
方法,因此您需要转换为对象类型,然后才能使用它


如果您通过接口访问此对象类型,则需要首先转换到
MessageService
type对象。

请考虑以下内容。你去比萨店,想试试他们的意大利香肠比萨。您想测试香肠切片机的工作原理吗?不。你想在你的比萨饼上看到五片意大利香肠——这是比萨饼店的要求。实际上,香肠是手工切的还是用切片机切的并不重要。您应该只验证所有需求是否正确实现


与您的类相同-它的要求是处理消息。不管消息的处理是如何实现的——不管它是否在内部调用某个helper方法。所以,我的建议总是一样的——不要测试私有方法——它们不需要存在,也不应该测试它们的存在。你去比萨店,想试试他们的意大利香肠比萨。您想测试香肠切片机的工作原理吗?不。你想在你的比萨饼上看到五片意大利香肠——这是比萨饼店的要求。实际上,香肠是手工切的还是用切片机切的并不重要。您应该只验证所有需求是否正确实现


与您的类相同-它的要求是处理消息。不管消息的处理是如何实现的——不管它是否在内部调用某个helper方法。所以,我的建议总是一样的-不要测试私有方法-它们不需要存在,也不应该测试它们的存在。

要回答为什么接口中的方法不是公共的问题:


界面设计是一种契约,并隐式公开。这是语言中的设计。因此,不需要使用关键字public。

来回答为什么界面中的方法不是public的问题:


界面设计是一种契约,并隐式公开。这是语言中的设计。因此,不需要使用关键字public。

不要仅仅为了单元测试而将
ProcessCustomer
公开!复习题目。它似乎不是代码显示的或者问题是什么。除了这里的其他答案,考虑制作一个<代码> CubServer处理器< /Cord>对象(或接口!)。
MessageService
可以在构造时(或无论如何)提供一个
CustomerProcessor
的实例,并使用它执行处理。然后,您可以编写单元测试来测试单个处理(在
CustomerProcessor
的上下文中),并为
MessageService
编写测试,从而通过模拟CustomerProcessor并验证每个客户是否已“处理”(即使技术上没有发生任何事情)。这是非常普遍的;不确定这是否适合您的实际代码。@ChrisSinclair-我还没有做到这一点,但是,是的,这是一个很好的观点和可能的设计。不要仅仅为了单元测试而将
ProcessCustomer
公开!复习题目。它似乎不是代码显示的或者问题是什么。除了这里的其他答案,考虑制作一个<代码> CubServer处理器< /Cord>对象(或接口!)。
MessageService
可以在构造时(或无论如何)提供一个
CustomerProcessor
的实例,并使用它执行处理。然后,您可以编写单元测试来测试单个处理(在
CustomerProcesso的上下文中)