C# 遵守单一责任原则的准则;单元测试

C# 遵守单一责任原则的准则;单元测试,c#,unit-testing,single-responsibility-principle,C#,Unit Testing,Single Responsibility Principle,我最近一直在阅读关于单一责任原则的概念,理论上我非常同意。我很难确定哪些准则可以准确地归类为违反原则。我希望实现这一原则,以便面向测试驱动的开发 以下面的代码为例: public void MarkAsSuccessful(PaymentMethodSpecific paymentMethod, bool requiresManualIntervention) { this.Paid = true; this.PaidOn = CS.Gen

我最近一直在阅读关于单一责任原则的概念,理论上我非常同意。我很难确定哪些准则可以准确地归类为违反原则。我希望实现这一原则,以便面向测试驱动的开发

以下面的代码为例:

public void MarkAsSuccessful(PaymentMethodSpecific paymentMethod, bool requiresManualIntervention)
    {
            this.Paid = true;
            this.PaidOn = CS.General_v3.Util.Date.Now;
            this.PaidByPaymentMethod = paymentMethod;
            this.RequiresManualIntervention = requiresManualIntervention;

            this.Update();

        this.CreateAndSendNotificationRegardingImmediatePayment();

        this.SendPaymentSuccessfulEmails();

    }
这被放在一个名为
PaymentRequest
的类中,该类基本上是一个处理电子商务应用程序中与支付相关的逻辑的类。上述方法将请求标记为“成功”。这必须标记支付栏以及其他信息,以及发送成功通知,并发送电子邮件


例如,当涉及到单元测试时,对这种方法进行单元测试是非常困难的,因为我无法知道通知是实际创建和发送的,以及支付电子邮件是否已发送。我想知道在SRP概念方面更有经验的人会如何处理这样一个例子

我猜您有一个
PaymentProcessor
类与
PaymentRequest
类合并/嵌入其中

PaymentProcessor
基本上是一个有限状态机,
PaymentRequest
通过它

在构建这个
PaymentProcessor
时,通常会注入处理“即时支付通知”和电子邮件的对象。通过这种方式,您可以通过注入声明预期条件已发生的模拟对象,独立地测试所有状态和处理器


单一责任本身是一个很好的概念,但当你开始整体投资实体时,力量就来了。

你可能会遇到更深层次的问题。你明白为什么名为
CreateAndSend…
的方法会违反SRP吗?@AustinSalonen我明白你的意思,但我不同意:如果他总是创建并发送通知呢?如果该方法只调用其他两个方法,则可以。SRP中一个非常常见的错误是试图在100%的时间内应用它。@AustinSalonen是的,我完全同意这个
PaymentRequest
类处理的责任比它实际应该处理的要多。注入/模拟对象将是一个很好的方法,可以测试该方法,而不必实际验证是否已发送了实际通知。