単体テストに適したアプリケーションをどのように設計するかについて問題があります。
私はSRP(Single-Responsibility Principle)を実装しようとしていますが、これには、コードをより整理された状態に保つために、ほとんどの機能を個別の専用クラスに分割することが含まれると理解しました。たとえば、私はこの特定のシナリオを持っています。
RecurringProfile
メソッドを持つクラス.ActivateProfile()
。この方法では、ステータスをアクティブとしてマークし、次の期日の次の(最初の)定期支払いを作成します。たとえば、別のクラスで次の定期支払いを作成するために、機能を分割するつもりでしたRecurringProfileNextPaymentCreator
。'RecurringProfile'
私の現在のアイデアは、このクラスにコンストラクターのパラメーターとしてをとらせることです。
RecurringProfileNextPaymentCreator(IRecurringProfile profile)
ただし、これは単体テストでは問題になると思います。機能をテストする単体テストを作成したいと思いActivateProfile
ます。IRecurringProfileNextPaymentCreator
このメソッドは、依存性注入(Ninject)を介してインスタンスを取得し、メソッドを呼び出します.CreateNextPayment
。
単体テストを作成するという私のアイデアは、のモックを作成し、それを置き換えて、実際にメソッドが呼び出されたIRecurringProfileNextPaymentCreator
ことを確認できるようにすることでした。.ActivateProfile()
ただし、コンストラクターパラメーターが原因で、これはNInjectのデフォルトコンストラクターとしては適合しません。そのような場合(ソリューション全体にそのようなクラスを多数持つことができる場合)のためにカスタムNInjectプロバイダーを作成する必要があるのは、少しやり過ぎでしょう。
これについてどのように取り組むかについてのアイデア/ベストプラクティスはありますか?
-以下は、上記の例に関するサンプルコードです:(コードは手書きであり、構文的に100%正しいわけではないことに注意してください)
public class RecurringProfile
{
public void ActivateProfile()
{
this.Status = Enums.ProfileStatus.Activated;
//now it should create the first recurring payment
IRecurringProfileNextPaymentCreator creator = NInject.Get<IRecurringProfileNextPaymentCreator>();
creator.CreateNextPayment(this); //this is what I'm having an issue about
}
}
そして、サンプルの単体テスト:
public void TestActivateProfile()
{
var mockPaymentCreator = new Mock<IRecurringProfileNextPaymentCreator>();
NInject.Bind<IRecurringProfileNextPaymentCreator>(mockPaymentCreator.Object);
RecurringProfile profile = new RecurringProfile();
profile.ActivateProfile();
Assert.That(profile.Status == Enums.ProfileStatus.Activated);
mockPayment.Verify(x => x.CreateNextPayment(), Times.Once());
}
サンプルコードに行くと、私の問題は、メソッドへのパラメーターとしてRecurringProfileを渡すのが良い習慣であるかどうか、またはインスタンスを取得するときに何らかの方法でDIフレームワークにcreator.CreateNextPayment()
渡す方が理にかなっているのかどうかです。 、は常に次の支払いを作成するために行動することを考慮して。これにより、質問がもう少し明確になることを願っています。RecurringProfile
IRecurringProfileNextPaymentCreator
IRecurringProfileNextPaymentCreator
IRecurringProfile