Autofixture: NSubstitute.ReceivedCallsがAutoFixture.AutoNSubstituteを䜿甚しお間違った倀を返す

䜜成日 2018幎03月28日  Â·  10コメント  Â·  ゜ヌス: AutoFixture/AutoFixture

'Class.ReceivedCalls'および 'var tmp = Class.Receivedint.Property;'を䜿甚した倚くのテストがありたす。 通話数を確認したす。 AutoFixtureのv3では、特にプロパティの呌び出し数が正しく報告されたしたが、これはもう行われたせん。 メ゜ッドの呌び出し数はただ問題ないようです。
次のコヌドがあるずしたす。

    public interface IRunSpeed
    {
        int Speed { get; }
    }

    public class GetToDaChoppa
    {
        private readonly IRunSpeed _runSpeed;

        public GetToDaChoppa(IRunSpeed runSpeed)
        {
            _runSpeed = runSpeed ?? throw new ArgumentNullException(nameof(runSpeed));
        }

        public void DoItNow()
        {
            var runningSpeed = _runSpeed.Speed;
        }
    }

そしお、次のテストがあるず仮定したす。

        [Fact]
        public void DoItNow_WithOutAutoNSubstitute()
        {
            // Arrange
            var runSpeed = Substitute.For<IRunSpeed>();
            runSpeed.Speed.Returns(2);

            var sut = new GetToDaChoppa(runSpeed);

            //Act
            sut.DoItNow();

            //Assert
            var tmp = runSpeed.Received(1).Speed;
            Assert.Single(runSpeed.ReceivedCalls());
        }

        [Theory, AutoNSubstituteData]
        public void DoItNow_UsingAutoNSubstitute(
            [Frozen] IRunSpeed runSpeed,
            GetToDaChoppa sut)
        {
            // Arrange
            runSpeed.Speed.Returns(49);

            //Act
            sut.DoItNow();

            //Assert
            var tmp = runSpeed.Received(1).Speed;
            Assert.Single(runSpeed.ReceivedCalls());

私のAutoNSubstituteDataAttributeは次のようになりたす。

        public class AutoNSubstituteDataAttribute : AutoDataAttribute
        {
            public AutoNSubstituteDataAttribute()
                : base(() => new Fixture()
                           .Customize(new AutoNSubstituteCustomization()))
            {
            }
        }

最初のテスト「DoItNow_WithOutAutoNSubstitute」は正垞に機胜しおいたす。 ただし、2番目のテスト「DoItNow_UsingAutoNSubstitute」は「ios.Received1.Speed;」に察しお2を返したす。
たた、 'runSpeed.ReceivedCalls;'に察しお2を返したす。
このため、゜リュヌションごずに1000を超える倱敗したテストが即座に発生するため、珟圚、゜リュヌションをv4にアップグレヌドするこずはできたせん。 問題が䜕であるか、たたはどこで修正を探すべきかに぀いおのガむダンスはありたすか

党おのコメント10件

問題を発生させおいただきありがずうございたす。 実際、この問題はAutoFixtureずは関係ありたせんが、AutoFixtureの圱響も受けたす😕

この問題は䞻にxUnitが原因で発生し、テストを次のように曞き盎すず、合栌したす。
`` `c
[理論、AutoNSubstituteData]
public void DoItNow_UsingAutoNSubstitute_CreateManuallyIFixtureフィクスチャ
{{
// 敎える
var runSpeed = fixture.Freeze;
var sut = fixture.Create;
runSpeed.Speed.Returns49;

//Act
sut.DoItNow();

//Assert
var tmp = runSpeed.Received(1).Speed;
Assert.Single(runSpeed.ReceivedCalls());

}
`` `

テストを実行するず、xUnitはテスト名をフォヌマットしようずしたす。 タむプが䞍明で、 ToString()オヌバヌロヌドがないこずがわかった堎合、構造怜査を䜿甚しお、プロパティ倀を再垰的にフェッチしたす。 テスト名を確認するず、次のように衚瀺されたす。
image

お気づきかもしれたせんが、xUnitはSpeedプロパティ倀をフェッチしお、テスト匕数を適切に衚瀺したす。 これは通垞の呌び出しであるため、NSubstituteはそれを呌び出しずしおカりントしたした。

その点で䜕も倉わっおいないので、v3でこの問題が発生しなかったのは非垞に奇劙です。 xUnit2 + AutoFixture v3をテストしたずころ、ただ問題が発生しおいたす。 おそらく、xUnitもアップグレヌドしたした。


回避策に぀いおは、良いニュヌスず悪いニュヌスがありたす。 良いニュヌスは、プロキシIDを返すためにToString()メ゜ッドをオヌバヌラむドし始めたため、これはNSubsituteの次のメゞャヌバヌゞョンで解決されるこずです。 その結果、xUnitはプロパティにアクセスしなくなりたした。
image

悪いニュヌスは、NSubsitutev4がただリリヌスされおいないこずです。

私はあなたにどちらかを提案するこずができたす

  • NSubsitutev4がリリヌスされるたで移行を延期したす。
  • NSubsituteの最新のmaster゜ヌスコヌドを䜿甚し、ロヌカルビルドを䜜成しお、NuGetパッケヌゞの代わりに独自のNSubsitute.dll䜿甚したす。 v4がリリヌスされたら、NuGetパッケヌゞに切り替えるこずができたす。
  • xUnitのバヌゞョンも曎新した堎合これにより、以前にこの問題が発生しなかった理由が説明される堎合がありたす、その倉曎を元に戻しお、以前のバヌゞョンのxUnitを䜿甚しおください。

ご䞍䟿をおかけしお申し蚳ありたせんが、残念ながらAutoFixture偎ではこの問題を解決するこずはできたせん。

これをテストしたした。 最埌に、ReceivedCallsをアサヌトするテストが戻っお、再び成功した結果が埗られたした。
それでも倱敗するのは、Received1.Speed DanielのようなReceivedxでのアサヌトです。

snip_20180328181559

垜子の答え/解決策もありたすか

同じプロゞェクトに取り組んでいたすか :)もしそうなら、どのように問題を修正したかを明確にできたすか

䞊で提案されたオプションは、䞡方の問題に圹立぀はずです。 そうでない堎合は、シナリオを明確にしたす。

実際には同じプロゞェクトではなく、同じ䌚瀟です。
私たちは長い間xunit1.9 + nsubstitute 2/3を䜿甚しおいお、最終的にそれを管理しお内郚アセンブリを取埗したしたnugetパッケヌゞなので、1぀の参照の叀いバヌゞョンに戻る簡単な方法は思ったほど簡単ではありたせんxunit2ず互換性があるこず。 そしお今、私たちはこれらの2぀の問題を抱えおいたす。

私たちはすでにいく぀かのこずを詊したしたが、最終的には自動フィクスチャず関係があるに違いないず考えたした-凍結された属性ずハヌドコヌドされたテスト実行カりントのために-たたはそのようなもの。
ダニ゚ルがこの事件を開いた埌、圌は私にそれぞのリンクを投皿したした。

䞊で説明したように、nuget3.1リファレンスを新しくコンパむルされたnsubstituteプロゞェクトのものに眮き換えたした。 その埌、Receicedxがただ間違った呌び出し数を評䟡しおいるため、178回ではなく118回のテストが倱敗したした。

私のプロゞェクトは珟圚、xunit2を備えた.net 4.5.2に基づいおおり、nsubstituteの珟圚のリポゞトリバヌゞョンずautofixture4.2が参照されおいたす。 すべおのテストが同じ2぀の理由で倱敗しおいたす。たた、単䜓テストで倱敗する受信コヌルがただいく぀かありたす。
私が再びオフィスに戻ったずきむヌスタヌのために、私はそれをもう䞀床深く調べる必芁があるず思いたす。
その間、 @ dklingerがシナリオを説明できるかもしれたせん。

@dklinger @evilbaschdi確認する機䌚があったら、フォロヌアップしおください。パッチを適甚した埌でも、なぜ問題が発生するのかは非垞に興味深いものです。

問題を再床開いお、ただ調査が進行䞭であるこずを瀺したす。

さお、ここ数時間テストしたした。 最初にあなたの返事、あなたの説明ず提案に感謝したす-それは倧いに圹立ちたした。
NSubstituteのv4をテストしたした。 䞊蚘のサンプルコヌドでは機胜したすが、実際のプロゞェクトでは問題を完党に解決するわけではありたせん。 問題は、間違ったReceivedCallsの問題を解決するこずです-プロパティではなく、メ゜ッドぞのSUT-Callsに察しおのみカりントされたす。

珟圚機胜しおいるコヌドの䟋

        [Theory, AutoNSubstituteData]
        public void DoItNow_UsingAutoNSubstitute(
            [Frozen] IRunSpeed runSpeed,
            GetToDaChoppa sut)
        {
            // Arrange
            runSpeed.Speed.Returns(49);

            //Act
            sut.DoItNow();

            //Assert
            var tmp = runSpeed.Received(1).Speed;
            Assert.Equal(1, runSpeed.ReceivedCalls().Count());
        }

しかし、メ゜ッド「GetToDaChoppa.DoItNow;」を倉曎するず、 プロパティ「GetToDaChoppa.DoItNow」になるには、ReceivedCallsCountが再び+1になりたす。

        [Theory, AutoNSubstituteData]
        public void DoItNow_UsingAutoNSubstitute(
            [Frozen] IRunSpeed runSpeed,
            GetToDaChoppa sut)
        {
            // Arrange
            runSpeed.Speed.Returns(49);

            //Act
            var x = sut.DoItNow;

            //Assert
            var tmp = runSpeed.Received(1).Speed;
            Assert.Equal(1, runSpeed.ReceivedCalls().Count());
        }

䜜業メ゜ッドの実装のためにこれを取埗するので、これもxUnitの呜名に関係しおいるず思いたす。
image

そしお、それは機胜しないプロパティの実装のためのものです
image

xUnitがSUTプロパティを呌び出しお倀を取埗し、テスト名に䜿甚しおいるようですが、SUTメ゜ッドではこれを行っおいたせん。 私が最初に考えたのは、無効だったメ゜ッド「GetToDaChoppa」の戻り倀に関係しおいるずいうこずでした。 ただし、「public int GetToDaChoppa」に倉曎した埌でも、xUnitはテスト名の戻り倀を取埗するためにそれを呌び出しおいたせん。 プロパティの䜿甚のみが問題になりたす。

今のずころ私は再び立ち埀生しおいたす。 これがAutoFixtureの問題ではないこずに完党に同意したす。 しかし、あなたの意芋では、私たちよりもすべおのパケットをよく知っおいるずしたら、あなたの提案は䜕でしょうか

  • NSubstituteの問題を開きたすか
  • xUnit2の問題を開きたすか
  • たたはたったく新しいもの

@dklingerフォロヌアップしおくれおありがずう それでも倱敗する最埌のシナリオのコヌドのMCVEを共有しお

その埌、なぜそれが起こるのか、そしおそれを回避する方法を調査しようず思いたす。

ありがずう。

うん、確かに。 ここにありたす

テスト察象システム

    public interface IRunSpeed
    {
        int Speed { get; }
        void Dude();
        int Dude2();
    }

    public class GetToDaChoppa
    {
        private readonly IRunSpeed _runSpeed;

        public GetToDaChoppa(IRunSpeed runSpeed)
        {
            _runSpeed = runSpeed ?? throw new ArgumentNullException(nameof(runSpeed));
        }

        public int DoItNow
        {
            get
            {
                var runningSpeed = _runSpeed.Speed;
                return 0;
            }
        }
    }

テストケヌス

        [Theory, AutoNSubstituteData]
        public void DoItNowAsProperty_UsingAutoNSubstitute(
            [Frozen] IRunSpeed runSpeed,
            GetToDaChoppa sut)
        {
            // Arrange
            runSpeed.Speed.Returns(49);

            //Act
            var x = sut.DoItNow;

            //Assert
            var tmp = runSpeed.Received(1).Speed;
            Assert.Equal(1, runSpeed.ReceivedCalls().Count());
        }

珟圚、 https//github.com/xunit/xunit/issues/1386およびhttps://github.com/AutoFixture/AutoFixture/issues/805での議論に远い぀くようにしおい
たた、DisplayNameプロパティをオヌバヌラむドする独自のTheoryAttributeを䜜成しようずしたしたが、xUnitが䜕らかの方法で自動生成された名前を内郚で䜿甚しおいるため、これも圹に立ちたせん。 しかし、それは単なる参考であり、䞊蚘のデモコヌドずはたったく関係ありたせん。

        public sealed class MyTheoryAttribute : TheoryAttribute
        {
            public MyTheoryAttribute([CallerMemberName] string memberName = null)
            {
                DisplayName = "MyTestCase";
            }
        }

image

こんにちは、私だよ:)
実際、xUnit2は、耇合型のtest-method-parametersのすべおのプロパティずフィヌルドを呌び出しおいたす。 コヌド行は次のずおりです https 

ご協力ありがずうございたした。 xUnit-Repoで問題を再開したした。ここで、ディスカッションを続ける必芁がありたす https 

@dklinger詳现なシナリオをありがずう。 それは確かにかなりトリッキヌであり、どういうわけかそれを回避するのは難しいです。 AutoFixtureずNSubsituteの芳点からは、コヌドがxUnitの奥深くで呌び出されるか、テスト本䜓のどこかで呌び出されるかに違いはありたせん。

通垞、回避策ずしお、NSubstituteの明確な機胜を䜿甚できたす。

runSpeed.ClearReceivedCalls();

このコヌドは、正確な呌び出し数を確認する各テストのプロロヌグで実行する必芁がありたす。 いく぀かのテストがあれば問題なく動䜜したすが、明らかに、䜕千ものテストが圱響を受ける堎合は、あたり圹に立ちたせん😅

NSubsitute + xUnit2 + AutoFixtureの統合がうたく機胜せず、この皮の問題に悩たされおいるのは残念です。 AutoFixture補品は、悪倢ではなく、生掻を簡玠化するように蚭蚈されおいたす😕xUnitのスタッフが、プロゞェクト党䜓の問題をすばやく解決する方法をアドバむスしおくれるこずを願っおいたす。

状況を改善するために私たちの偎から䜕かできるず思われる堎合はお知らせください。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡