0

I have a interface that has an indexed property that I need to mock.

public interface MultipleLines
{
    [DispId(201)]
    int Count
    {
        [MethodImpl(MethodImplOptions.InternalCall)]
        [DispId(201)]
        get;
    }

    [DispId(202)]
    SomeLine this[[In] int Index]
    {
        [MethodImpl(MethodImplOptions.InternalCall)]
        [DispId(202)]
        [return: MarshalAs(UnmanagedType.Interface)]
        get;
    }}

How can I give value to MultipleLines.Item[0/or any number ] with Fake It easy ? This is the test I tried to write:

    [Fact]
    public void Test1()
    {
        var myValue = new SomeLine();
        var mockedLines = A.Fake<MultipleLines>();
        A.CallTo(() => mockedLines.Item[1]).Returns(myValue);
    }

This simple call works perfectly:

var line= mockedLines.Item[1];
  • Your code seems correct. Are you getting an error? – Thomas Levesque Apr 26 '23 at 17:25
  • What I meant was, your fake setup seems correct. But you're not actually testing anything... What are you trying to test? What is your SUT (system under test)? It doesn't appear anywhere in the code you showed. – Thomas Levesque Apr 26 '23 at 17:59
  • The error that I get is the following: "An expression tree may not contain an indexed property ". – Székely Réka Apr 27 '23 at 07:54
  • I have a code which converts a geometric model, including lines, arcs and points in 3D into another type of model. I want to test the conversion of a simple line. Shortly: var mockedModel =A.Fake(); A.CallTo(() => mockedModel.Lines.Item[1].StartNode).Returns(new RNode() { x= 100, y= 200, z=1000}); var convertedLine = LineConverter.ToMyLineType(mockedModel.Lines.Item[1], mockedModel.Nodes); Assert.Equals( 100, convertedLine.StartNode.X); Assert.Equals( 200, convertedLine.StartNode.Y); Assert.Equals( 1000, convertedLine.StartNode.Z); – Székely Réka Apr 27 '23 at 08:10
  • 1
    The error might be related to the fact that it's a COM interface. See this answer: https://stackoverflow.com/a/11521437/98713 – Thomas Levesque Apr 28 '23 at 04:19
  • Thank you, that is working! Please post it as an answer. – Székely Réka Apr 28 '23 at 07:52
  • Done (*extra chars to reach the minimum length*) – Thomas Levesque Apr 28 '23 at 13:18

2 Answers2

1

I think you've accessing the property incorrectly.

 A.CallTo(() => mockedLines[1]).Returns(myValue);

works for me.

That is, this test passes:

[Fact]
public void Test1()
{
    var myValue = new SomeLine();
    var mockedLines = A.Fake<MultipleLines>();
    A.CallTo(() => mockedLines[1]).Returns(myValue);

    mockedLines[1].Should().BeSameAs(myValue);
}
Blair Conrad
  • 233,004
  • 25
  • 132
  • 111
1

Your interface seems to be a COM interface, and I think your problem might come from that. COM interop is a bit weird.

Try to use this syntax instead:

A.CallTo(() => mockedLines.get_Item(1)).Returns(myValue);

I think this trick isn't necessary with recent version of C#, but I might be mistaken. Out of curiosity, which version of C# are you using?

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758