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

Add the ability to compare ref argument by value #1437

Open
SoggyBottomBoy opened this issue Nov 4, 2023 · 1 comment
Open

Add the ability to compare ref argument by value #1437

SoggyBottomBoy opened this issue Nov 4, 2023 · 1 comment

Comments

@SoggyBottomBoy
Copy link

I have some code that is calling into a COM library in which arrays are passed by reference. Our internal API which requires testing takes in an object and is responsible for creating the array which is passed in by reference. I am trying to test that our function given an object calls the COM API with the appropriate values. I can do this for any argument which is not passed by ref, but can not do the same for ref arguments. The problem is that in my test method I cannot create the array in which to test as this is compared by reference and is therefore not the same as the array generated by our API.

I'm thinking of something which is similar to It.Is(Func<T, bool> predicate) for It.Ref. My understanding is that moq checks whether the argument is ref and if the verify method is It.Ref.IsAny is used for comparison then treats it as a special case otherwise it requires a constant value.

The problem

public static int MyMethodToTest(COMLibrary lib, MyObject obj)
{
    var values = obj.ToArray();
    return lib.Function(ref values);
}

[Fact]
public void MyTest()
{
    // Arrange
    var comLib = new Mock<COMLibrary>();

    var obj = MyObject();
    var expected = new[] { 0 }

    // Act
    MyMethodToTest(obj);

    // Assert
    comLib.Verify(f => f.Function(ref expected), Times.Once); // Fails as expected is not equal by reference
}

Suggestion

Either
a) when a ref argument uses It and It defines the compare predicate the RefMatcher should match with the predicate

[Fact]
public void MyTest()
{
    // Arrange
    var comLib = new Mock<COMLibrary>();

    var obj = MyObject();
    var expected = It.Is((int[] input => input.SequenceEquals(new[] { 0 }));

    // Act
    MyMethodToTest(obj);

    // Assert
    comLib.Verify(f => f.Function(ref expected), Times.Once);
}

b) same but use It.Ref with a predicate, which may be more inline with how ref agruments are treated in other scenarios (i.e. it's expected that If.Ref is used in combination wtih ref arguments

@kzu kzu added the enhancement label Dec 6, 2023
@jobwttraining
Copy link

I would like to see this enhancement as well. The new version of Autofac uses in parameters and we mock some Autofac functions in our tests where we can now only use It.Ref<>.IsAny, but we would like to use It.Ref<>.Is(p => p.Name == "Test") to support multiple setups with different results.

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

No branches or pull requests

3 participants