Future mocking of MarshalByRefObject in xUnit with InlineData hangs (never completes)

1 Answer 36 Views
Continuous Integration General Discussions
Jeremy
Top achievements
Rank 1
Jeremy asked on 05 Jul 2022, 07:52 PM | edited on 05 Jul 2022, 10:32 PM

I'm working on tests for legacy code that instantiates a ServiceController (in System.ServiceProcess) to check for a running SQL Server instance. I want to add the tests to our CI/CD build pipeline, so I decided to use JustMock to future-mock ServiceController since the service in question will not exist on the build server. These tests are all using xUnit.

However, the test (which has 3 variants specified via xUnit's InlineData attributes) started hanging on the first variant. It's not just long-running; I've let it run for hours (it's normally a 3-second test at most), and CPU usage is negligible. ServiceController is IDisposable, so I figured it might have something to do with that.

After a lot of paring down, I can repro the problem with the following code in a new project:

public class JustMockTest
{
    [Theory]
    [InlineData("test")]
    public void TestMethod(string whatever)
    {
        Mock.Arrange(() => new ServiceController()).DoNothing();
    }
}

However, this test (in the same class) works fine and completes in about 1s - note that it's a fact, not a theory:

[Fact]
public void TestMethod2()
{
    Mock.Arrange(() => new ServiceController()).DoNothing();
}

This is JustMock v2022.1.223.1, xUnit v2.4.1.0, and VS 2022.

At first I wondered if my 3 variants were somehow stepping on each other's Mock.Arrange() statements; but as you can see, the top test, while declared as a theory, only has 1 variant and still has the problem. What's also interesting is that an analogous setup for MSTest also runs fine - so this seems to be xUnit-specific somehow:

[TestClass]
public class UnitTest1
{
    [DataTestMethod]
    [DataRow("test")]
    [DataRow("test2")]
    public void TestMethod1(string whatever)
    {
        Mock.Arrange(() => new ServiceController()).DoNothing();
    }
}

At first I thought IDisposable classes may be the problem, but it seems it's actually MarshalByRefObject; it's a base class of ServiceController and others I can repro with (WebClient, MemoryStream, etc.), and I can also repro by mocking a simple class of my own that extends MarshalByRefObject.

Is this a known issue? Are there recommended workarounds (without having to ditch xUnit for MSTest or another framework)?

Thanks!
Jeremy

Jeremy
Top achievements
Rank 1
commented on 05 Jul 2022, 07:58 PM | edited

Sorry, I noticed a couple issues w/ the title: it mentions future mocking because I was trying to use that at some point, but it's not specific to that (nor does future mocking appear in my question); and I meant to say MarshalByRefObject, not MarshalByRefFixture. I don't see how to rename the question, though.

However, I found this thread just a few minutes ago that feels like the same issue. There's been some bouncing around between JustMock and xUnit, so at this point I don't know where the problem lies:

https://www.telerik.com/forums/xunit-justmock-fatal-error---system-argumentexception

I just tested adding this xUnit setting to my app.config file in the test project per that thread, and it seems to work:

<add key="xunit.appDomain" value="denied" />

... but I'm not 100% sure of what the other ramifications could be, and if possible I'd also like to verify whether it's just a workaround or if it really solves the root cause. In short, not sure how much to trust it as a true solution.

1 Answer, 1 is accepted

Sort by
0
Accepted
Ivo
Telerik team
answered on 06 Jul 2022, 01:30 PM

Hello Jeremy,

The most probable reason for this behavior is the multiple domains used in test execution. As you have already said, the problem is rooted in MarshalByRef object, and using future mocking could leave it uninitialized (as a base class). Regarding the solution, in my opinion, it could be considered safe and reliable since it avoids multiple domain creation which affects mainly marshaling.

Regards,
Ivo
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Jeremy
Top achievements
Rank 1
commented on 06 Jul 2022, 09:25 PM

Understood, Ivo - thanks!
Ivo
Telerik team
commented on 07 Jul 2022, 08:16 AM

You are welcome, Jeremy! If you have any further comments or concerns do not hesitate to write back.
Tags
Continuous Integration General Discussions
Asked by
Jeremy
Top achievements
Rank 1
Answers by
Ivo
Telerik team
Share this question
or