Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StackOverflowException on VerifyAll when mocked method returns mocked object #1012

Closed
hotchkj opened this issue Apr 28, 2020 · 2 comments · Fixed by #1014
Closed

StackOverflowException on VerifyAll when mocked method returns mocked object #1012

hotchkj opened this issue Apr 28, 2020 · 2 comments · Fixed by #1014
Labels
Milestone

Comments

@hotchkj
Copy link

hotchkj commented Apr 28, 2020

This issue started appearing when we upgraded to Moq 4.14.0. Prior Moq versions do not exhibit this behaviour. The associated unit testing library is xunit, in case that has any impact.

  • Moq: 4.14.0
  • xunit: 2.4.1
  • Visual Studio: 2019 16.5.3

A pattern that a set of our code is using is to verify a strict repository during test cleanup for ease of writing tests.

The relevant lines of code seem to be:

// mock Setup returns itself (i.e. real code would 'return this')
path.Setup(x => x.AddPathFragment("fragment")).Returns(path.Object);
Repository.VerifyAll();
Full reproduction code that fails is in this collapsed section:
using System.Threading.Tasks;
using Moq;
using Xunit;

namespace Autodesk.Extensions.Mocking.Tests
{
    public interface IBuildPath
    {
        IBuildPath AddPathFragment(string fragment);
    }

    public class ClassUnderTest
    {
        private readonly IBuildPath _path;

        public ClassUnderTest(IBuildPath path)
        {
            _path = path;
        }

        public async Task TestMethod()
        {
            _path.AddPathFragment("fragment");

            await Task.Delay(1).ConfigureAwait(false);
        }
    }

    public class MockTestClass2
    {
        protected MockRepository Repository { get; } = new MockRepository(MockBehavior.Strict);
    }

    public class PathTestClass : MockTestClass2
    {
        [Fact]
        public async Task ExpectPath()
        {
            var path = Repository.Create<IBuildPath>();

            var underTest = new ClassUnderTest(path.Object);

            path.Setup(x => x.AddPathFragment("fragment")).Returns(path.Object);

            await underTest.TestMethod().ConfigureAwait(false);

            Repository.VerifyAll();
        }
    }
}

Please let me know if any further details are needed. Hopefully we're not doing anything unexpected/silly!

Expected Outcome:
Code verifies as in Moq 4.13 & does not crash the test provider.

Actual Outcome:

---------- Starting test run ----------
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.1 (32-bit Desktop .NET 4.0.30319.42000)
[xUnit.net 00:00:00.57]   Starting:    My.Mocking.Tests
The active test run was aborted.
Reason: Test host process crashed : Process is terminated due to StackOverflowException.

The exception is reported as entirely in native code, so unfortunately I cannot provide any meaningful callstack.

@hotchkj hotchkj changed the title StackOverflowException when VerifyAll is called in test Dispose and mocked method returns itself StackOverflowException on VerifyAll when mocked method returns mocked object Apr 28, 2020
@stakx
Copy link
Contributor

stakx commented Apr 28, 2020

Nice catch @hotchkj, thanks for reporting this. A bug fix for this is underway, expect a new patch release shortly.

@stakx
Copy link
Contributor

stakx commented Apr 28, 2020

@hotchkj an updated Moq version (4.14.1) should become available on NuGet shortly. If there are any further problems, please report them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants