1

私は次のコードを持っています:

        using System;
        using NUnit.Framework;
        using Rhino.Mocks;

        public class A
        {
        }

        public class B
        {
        }

        public interface IStatementExecutor
        {
            void Exec(string statement);
        }

        public abstract class Foo<T>
        {
            private readonly IStatementExecutor _statementExecutor;
            private readonly string _targetSegment;

            protected Foo(IStatementExecutor statementExecutor, string targetSegment)
            {
                _statementExecutor = statementExecutor;
                _targetSegment = targetSegment;
            }

            public void Update(T item)
            {
                _statementExecutor.Exec("sp_" + _targetSegment + "Update");
            }
        }

        public class Bar : Foo<A>
        {
            public Bar(IStatementExecutor statementExecutor)
                : base(statementExecutor, "ATable")
            {
            }
        }

        public class Baz : Foo<B>
        {
            public Baz(IStatementExecutor statementExecutor)
                : base(statementExecutor, "BTable")
            {
            }
        }

        [TestFixture]
        public class Foo_Tests
        {
            [Test]
            public void Update_CallsStatementExecutorWithTableName()
            {
                const string tableName = "TestTable";
                var mockStatementExecutor = MockRepository.GenerateMock<IStatementExecutor>();
                mockStatementExecutor.Expect(m => m.Exec("sp_" + tableName + "Update"));
                var sut = MockRepository.GeneratePartialMock<Foo<A>>(mockStatementExecutor, tableName);
                var testModel = new A();


                sut.Update(testModel);

                mockStatementExecutor.AssertWasCalled(m => m.Exec("sp_" + tableName + "Update"));
            }
        }

基本クラスの単体テストはすでにありますFoo<T>Bar基本クラスはすでにカバーされているので、派生クラスと。に対して同一のテストを記述したくありませんBaz

派生クラスで私が本当に気にかけているのは、正しい文字列targetが基本クラスに渡されることだけです。

派生クラスのカプセル化を壊したり、冗長な単体テストを記述したりせずに、これを単体テストする方法に苦労しています。

targetしたがって、問題は、パラメータの派生クラスから基本クラスに正しい値が渡されることをテストするにはどうすればよいですか?

(答えが「compositionを使用する...」の場合は、上記から変更したコードサンプルを使用してバックアップしてください。

ありがとう!

4

3 に答える 3

2

BTableの代わりにZTableをそこに置くと何か悪いことが起こると予想されるので、BarとBazの他の方法でテストする可能性が高いと思います。

Fooに、渡されたものを返すメソッドを追加できます。

次に、子孫を作成した後、それを呼び出し、期待値に対して検証します。

またはあなたは次のようなことをすることができます

public class Bar : Foo<A>     
{         
  private static String _tableName = "ATable";
  public String  TableName {get {return _tableName;}}
  public Bar() : base(_tableName)         
  {         
  }     
} 

次に、testBar.TableNameをテストできます

もう1つのオプションは、TがTableNameプロパティを持つ構造体またはクラスである場合、このためだけにBarおよびBazの子孫は必要ありません。

于 2012-07-27T16:01:57.110 に答える
0

FooおよびBarユニットテストメソッドは、一般的なテストコードを含むヘルパーメソッドを呼び出すことができます。

于 2012-07-27T15:44:25.710 に答える
0

これはさまざまな方法で実行できます。TypeMockのようなモックフレームワークを使用してベースクラスを効果的にモックし、内部変数に関するより多くの情報をTypeMockから取得する1つの方法。

しかし、あなたの投稿からは明らかに明らかではありませんが、なぜ基本クラスが特定の理由でバークラスによって使用されることが重要なのか。テストする方法がないため、これは明確ではありません。Barつまり、期待どおりに使用されていることを保証するために監視できる外部動作はありませんFoo。コンソール出力をリダイレクトしてから、その出力を監視して検証を行うことができます。しかし、それが本当にあなたが探しているものではないと思います。

よりテスト可能な例を提供する必要があります。テキストを出力するだけでなく、テストで観察できる実際の動作をしたもの。

于 2012-07-27T15:50:52.700 に答える