3

OOコードの各ユニットを単体テストするには、保護する必要があるメソッド、またはおそらくプライベートのメソッドであっても、アクセス修飾子をパブリックに設定する必要があることに気付きました。これは大丈夫ですか?

public class EnforceBusinessRules
{
    BusinessState m_state;

    public EnforceBusinessRules()
    {
        m_state = START;
    }


    public bool isInputcurrentlyFormatted(string input)
    {
        //code goes here to ensure the input passes formatting test
        //modify m_state appropriately
    }


    public bool InputContainsValidStartAndEndTokens(string input)
    {
        //code goes here to ensure that the start and end tokens of the input are of the type available in the system
        //modify m_state appropriately
    }


    public bool StartEndCommandisValidAccordingtoCurrentSystemSettings(string input)
    {
        //code goes here to check the start and End codes match the current start and end codes for the day
        //modify m_state appropriately
    }

    // and so on 
}
4

6 に答える 6

6

ユニットテストは「ブラックボックス」テストです。外部から見える要素のみをテストする必要があります。すべての内部動作をテストする場合、すべての単体テストを変更せずにコードを正しくリファクタリングすることはできません。

于 2012-06-03T12:52:32.580 に答える
1

テストする必要のあるプライベートメンバーのコードがたくさんあるためにアクセス修飾子を変更する必要がある場合は、クラスが大きすぎることを示している可能性があります。テストする動作を、テスト可能なパブリックインターフェイスを備えた小さなクラスに分割することを検討してください。あなたのコードは神オブジェクトコードの臭いに苦しんでいる可能性があります。

保護されたメンバーは、可能なクライアントのスペースがはるかに小さいことを除いて、パブリックメンバーと非常に似ていることに注意してください(派生クラスのみ)。テストのみが使用する派生オブジェクトを作成することで、これらのメソッドの単体テストを検討できます。このようにして、クライアントが使用するのと同じ方法でこれらのメソッドをテストします。

コードを変更する1つの方法は次のとおりです。

public class EnforceBusinessRules
{
    BusinessState m_state;

    public EnforceBusinessRules(IEnumerable<Rule> rules)
    {
        m_state = START;
    }

    public void Enforce(string input)
    {
        foreach (var rule in rules)
        {
            m_state = rule.EnforceRule(input);
        }
    }
}

public interface Rule
{
    public BusinessState EnforceRule(string input);
}

public class IsInputcurrentlyFormatted : Rule
{
    public BusinessState EnforceRule(string input)
    {
        //code goes here to ensure the input passes formatting test
    }
}

public class InputContainsValidStartAndEndTokens : Rule
{
    public BusinessState EnforceRule(string input)
    {
        //code goes here to ensure the input passes formatting test
    }
}

public class StartEndCommandisValidAccordingtoCurrentSystemSettings : Rule
{
    public BusinessState EnforceRule(string input)
    {
        //code goes here to ensure the input passes formatting test
    }
}

// and so on
于 2012-06-03T13:00:19.707 に答える
0

いいえ。私の意見では、あなたはそれについて間違って考えています。公開せずに推測することができます。プロパティの値は、たとえば関数の戻り値から実現できます。

保護されたメンバーの場合。それが何を意味するのか自問してみてください。これは、派生クラスがそのメンバーにアクセスできることを意味します。したがって、テストで派生型を作成します。

于 2012-06-03T12:54:58.360 に答える
0

通常、メソッド/クラス/プロパティ/その他を公開したくない外部に公開することはお勧めできません。私が働いているところでも同様の問題に遭遇しました。これらのパブリックメソッドは、ある時点ですべてのプライベートメソッドを呼び出す必要があるため、パブリックメソッドとプロパティにヒットするテストを作成しました。内部クラス/プロパティ/メソッドがある場合は、InternalsVisableToそれらの属性を使用して、単体テストライブラリにアクセスできます。

[assembly: InternalsVisibleTo("AssemblyB")]

http://msdn.microsoft.com/en-us/library/0tke9fxk.aspx

于 2012-06-03T13:02:44.577 に答える
0

プライベートデータが正しくカプセル化されるように、getterメソッドとsetterメソッドを作成できていないようです。

単体テストは、ゲッターとセッターを介してデータにアクセスする必要があります。

クラスコードでコラボレーションオブジェクトをインスタンス化することは避け、代わりにそれらの依存関係を挿入してください。

于 2012-06-03T13:04:54.497 に答える
0

プライベートまたは保護されたプロパティまたはメソッドをテストする必要がある場合は、機能を個別のクラスに抽出する必要があります。各クラスは1つのことだけを行う必要があります(単一責任原則)。プライベートメソッドがクラスの主な目的で二次機能を実行する可能性があります。

抽出すると、2つの良いことが起こります。1つは、テストするコードに単体テストで完全にアクセスできるようになったことです。次に、EnforceBusinessRulesクラスでそれについて心配する必要はありません。

于 2012-06-04T07:49:38.147 に答える