0

MoQ を使用して部分スタブを作成するコードがあります。インターフェイスの実装が異なる場合に単体テストを変更する必要がないように、具体的な実装ではなくインターフェイスとやり取りすることをお勧めします。

たとえば、次のようなファクトリ メソッドがあります。

private Mock<ISomeInterface> ISomeInterfaceStubFactory()
{
    return new Mock<SomeConcreteImplementation>();
}

メソッドを呼び出すコードは次のとおりです。

var partialStub = ISomeInterfaceStubFactory();            
partialStub.Setup(m => m.MethodToStubOutThatMethodToTestCalls(It.IsAny<string>())).Returns(new List<SomeOtherObject>());
partialStub.CallBase = true;

var actualResult= partialStub.Object.MethodToTest();

Assert.That(actualResult, Is.EqualTo(expectedResult));

問題は、これを行うと ISomeInterfaceStubFactory がコンパイルされないことです。そこで以下のように変更したのですが、こうすると部分スタブが壊れてしまうようです。スタブ化されたバージョンではなく、実際に実装されMethodToStubOutThatMethodToTestCallsた操作が呼び出されます。基本的には、スタブ オブジェクトでポリモーフィズムを使用しようとしています。とにかくこれを行うことはありますか?単体テストが具体的な実装と強く結び付けられないようにしたいと思います。

private Mock<ISomeInterface> ISomeInterfaceStubFactory()
{
    return new Mock<SomeConcreteImplementation>.As<ISomeInterface>();
}
4

2 に答える 2

2

モックオブジェクトのポイントが欠けていると思います。具体的な実装からモックを返すことは意味がありません。アイデアは、テスト対象のクラスを、モックできるインターフェイスまたは抽象に依存させることです。

于 2010-10-08T18:28:13.230 に答える
0

あなたの説明に従って私の答えを修正します。私は arootbeer に同意しませんが、あなたが何をしているのか、そしてなぜそれがうまくいかないのかを理解したいと思っています。

これは、あなたがやろうとしていることの簡単な例です。両方の具体的な実装でテストに合格しました。これはあなたがやろうとしていることですか、そしてこの例はあなたにとってうまくいきますか?

インターフェイスとクラス:

using System;

namespace ClassLibrary1
{
    public interface IFoo
    {
        string GetBaseString();
        string GetExtendedString();
    }
    public class Foo_A : IFoo
    {
        public virtual string GetBaseString()
        {
            return "Foo_A";
        }
        public virtual string GetExtendedString()
        {
            return GetBaseString() + "_Bar";
        }
    }
    public class Foo_B : IFoo
    {
        public virtual string GetBaseString()
        {
            return "Foo_B";
        }
        public virtual string GetExtendedString()
        {
            return GetBaseString() + "_Bar";
        }
    }
}

単体テスト:

using System;
using Xunit;
using Moq;

namespace ClassLibrary1.UnitTests
{
    public class Class1
    {
        [Fact]
        public void GetExtendedString_ReturnsExtendedString()
        {
            var partialFoo = IFooFactory();

            partialFoo.Setup(x => x.GetBaseString()).Returns("Foo");
            partialFoo.CallBase = true;

            string result = partialFoo.Object.GetExtendedString();

            Assert.Equal("Foo_Bar", result);
        }

        private Mock<IFoo> IFooFactory()
        {
            return new Mock<Foo_A>().As<IFoo>();
            //return new Mock<Foo_B>().As<IFoo>();
        }
    }
}
于 2010-10-10T18:16:31.680 に答える