-
-
Notifications
You must be signed in to change notification settings - Fork 805
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
Failure when invoking a method with by-ref parameter & mockable return type on a mock with CallBase
and DefaultValue.Mock
configured
#1249
Comments
in
parametersin
parameters
And yes, I'm aware that using |
Thanks for reporting, @IanKemp. I'll look into it as soon as I find a spare moment. |
@IanKemp, based on your repro code, I've managed to derive a failing unit test that uses Moq exclusively: public class Mockable { }
public interface IFoo
{
Mockable DoSomething(in int arg);
}
[Fact]
public void Test()
{
var mock = new Mock<IFoo>() { CallBase = true, DefaultValue = DefaultValue.Mock };
_ = mock.Object.DoSomething(1);
} The problem appears to surface if all of the following conditions hold:
(1) and (2) are necessary to get to this line of code. (3) is necessary to get past the (I used a few more test cases to track down this issue, click here to see them.) public class Issue1249
{
public sealed class Sealed { }
public class NonSealed { }
public interface IUseSealed
{
Sealed DoSomething(int arg);
}
public interface IUseInSealed
{
Sealed DoSomething(in int arg);
}
public interface IUseNonSealed
{
NonSealed DoSomething(int arg);
}
public interface IUseInNonSealed
{
NonSealed DoSomething(in int arg);
}
[Fact]
public void TestSealed()
{
var mock = new Mock<IUseSealed>() { CallBase = true, DefaultValue = DefaultValue.Mock };
_ = mock.Object.DoSomething(1);
}
[Fact]
public void TestInSealed()
{
var mock = new Mock<IUseInSealed>() { CallBase = true, DefaultValue = DefaultValue.Mock };
_ = mock.Object.DoSomething(1);
}
[Fact]
public void TestNonSealed()
{
var mock = new Mock<IUseNonSealed>() { CallBase = true, DefaultValue = DefaultValue.Mock };
_ = mock.Object.DoSomething(1);
}
[Fact]
public void TestInNonSealed()
{
var mock = new Mock<IUseInNonSealed>() { CallBase = true, DefaultValue = DefaultValue.Mock };
_ = mock.Object.DoSomething(1);
}
} Your suggested fix is almost correct. I suspect that the only thing still wrong with it is that you're checking for I'd therefore suggest the following change here: for (int i = 0; i < n; ++i)
{
+ var parameterType = parameterTypes[i];
+ if (parameterType.IsByRef)
+ {
+ parameterType = parameterType.GetElementType();
+ }
- arguments[i] = E.Constant(invocation.Arguments[i], parameterTypes[i]);
+ arguments[i] = E.Constant(invocation.Arguments[i], parameterType);
} Are you interested in submitting a PR for that? (If so, please include the unit test(s) and an entry in the changelog.) |
in
parametersCallBase
and DefaultValue.Mock
configured
NOTE: this is not a dupe of #1148 - my problem code is not using generics.
Apologies in advance if this is unclear - the tests in the repro solution I've attached should be more eloquent than my writing.
The repro uses AutoMoq because I haven't been able to trigger this issue in Moq directly, but the stack trace generated points directly to Moq as the culprit.
Describe the Bug
Given an object
<OuterService>
That has a constructor dependency on an interface
<InnerDependency>
And
<InnerDependency>
defines a method that accepts a parameter decorated with thein
modifierAnd
<OuterService>
defines a method that calls the previously-mentioned method on<InnerDependency>
When attempting to AutoMoq
<OuterService>
using the following:Moq 4.17.2 fails:
but only if the
in
parameter on <IInnerDependency> is a non-primitive object type - if you usestring
, there is no exception (i.e. it works as expected)!Based on the above stack trace it looks like this line is the problem. I think it needs to be changed to something like:
I haven't pulled this repo's source and tried the above, but a quick console app I whipped up (included in the repro) uses this approach and seems to work.
Scenario
Attached. There are 2 tests:
in
parameter (fails)string
as thein
parameter (passes)Expected Behavior
The first scenario (dependency with POCO as
in
parameter) works.The text was updated successfully, but these errors were encountered: