2

例:

public interface IFoo
{
    bool DoSomething();
}

public class Foo:IFoo
{
    public bool DoSomething()
    {
        var result = DoOtherThing();
        ...
        return result;
    }

    public bool DoOtherThing()
    {
        ...
    }
}

DoSomething()私の通常の TDD アプローチは、とDoOtherThing()メソッドの両方で単体テストを作成することです。DoOtherThingしかし、これが非公開の方法である場合、これを行うのは非常に困難です。また、プライベート メソッドをテストすることは禁止されていることも読みました。

クラスの目的がその (IFoo) インターフェイスを介してのみアクセスされる場合でも、コード カバレッジとテストを容易にするために、クラスにパブリック メソッドを持つことは容認できると考えられますか? 通常、インターフェイスのスコープ外にあるメソッドをプライベート メソッドとして配置しますが、これではすべてのコードを効率的にテストすることはできません。メソッドをパブリックにすると、Fooクラスの正しいテストが可能になりますが、少なくとも私には、クラスの外部から呼び出されないパブリック メソッドを持つことは正しくないように思えます。この方法はTDDに最適と考えられていますか、それともより良い方法がありますか?

4

3 に答える 3

6

パブリック メソッドは、アクセス可能である必要があるため、パブリックです。外部から呼び出されることが意図されていない場合は、プライベートにします。

コード カバレッジを取得できない場合は、クラスを複数のクラスに分割し、代わりにコンポジションを使用することをお勧めします。

テストが難しいものは、通常、設計上の欠陥を示しています。

アップデート

では、メールを送信する方法があるとしましょう。ステップ 1 では、MailMessage クラスを生成してデータを入力します。ステップ2はメールを送信しています

それが 2 つの責任 (SRP) です。メールを作成して実際に送信します。同じクラスではやらない。すべての電子メール クラスがメッセージを作成してから送信する場合も、コードの重複になります。ネットワーク障害をどのように処理しますか? それらのチェックも複製しますか?

次のようにします。

public class SendWelcomeEmailComposer
{
    MailMessage Compose(User user)
}

public class EmailSender
{
    void SendEmail(MailMessage);
}

public class EmailService
{
    void SendWelcomeEmail(User user)
    {
        // compose email
        // and send using the classes above.
    }
}

更新 2

プライベート メソッドをテストすべきではない理由は、品質測定に関する限りです。テスト カバレッジが低い場合は、いくつかの基本原則 (SOLID) に違反している可能性があります。

そのため、プライベート メソッドをテストするよりも、時間をかけてクラスの設計を熟考することをお勧めします。

于 2012-09-06T15:49:44.100 に答える
2

ここでのトリックは使用することです

[assembly: InternalsVisibleTo("NameOfYourTestAssembly")] 

AssemblyInfo.cs ファイル内。

これにより、テスト可能なメソッドを内部にすることができます。つまり、作成中のアセンブリと、この属性のアセンブリでのみアクセスできます。

(Mycode.dll と Mycode.Tests.dll がある場合は、属性を MyCode/Properties/AssemblyInfo.cs に追加します)

于 2012-09-06T15:55:35.453 に答える