Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resolving an anonymous type [duplicate]

My API returns an object, populated with an anonymous type. I can GET it through HTTP and it resolves to a json.
But... my unit test for the same method cannot resolve the anonymous type.
Dotnet framework 4.7.2 is used.

The code below shows the caller, in one project
and the callee, in another project,
with 2 different, failed, attempts. The second is copied from SO and here and there is no comment it doesn't work. But... it doesn't for me.

The error message is:

System.InvalidCastException : Unable to cast object
of type '<>f__AnonymousType1`2[System.String,System.String]'
to type '<>f__AnonymousType0`2[System.String,System.String]'.

where one can see the types are different.
But then IIRC there was a dotnet update some time ago that solved this issue to let them be "equal".


I am trying to resolve a use case by returning an anonymous type from a dotnet framework web api.
(there are other solutions, like dynamic, reflection, types or more endpoints but that is another question)
Note that HTTP is not involved in this test case, it is purely a dotnet framework issue.

WebAPI (project 1):

public class MyController: ApiController
{
    public object Get(string id)
    {
        return new { Key = id, Value = "val:" + id };
    }
}

Test (project 2):

[Fact]
public void MyTest
{
    var sut = new MyController();

    // Act.
    dynamic res = sut.Get("42");

    // Assert.

    // First attempt:
    Assert.Equal("42", res.Key);

    // Second attempt:
    var a = new { Key = "", Value = "" };
    a = Cast(a, res);  // <- the code fails already here

    Assert.Equal("42", a.Key);
}

private static T Cast<T>(T typeHolder, object x)
{
    // typeHolder above is just for compiler magic
    // to infer the type to cast x to
    return (T)x;
}


like image 429
LosManos Avatar asked Oct 28 '22 03:10

LosManos


1 Answers

Anonymous types aren't good for any scenario involving type testing, especially between assemblies. In some scenarios value-tuples (or the class tuples, since a value-tuple would be boxed here anyway) might be useful to you, or you could define a real proper type.

Otherwise: it is fine to test anonymous types (or any types) by looking at the shape with reflection (does it have features X/Y/Z?) - but without doing a test on the actual runtime type.

like image 185
Marc Gravell Avatar answered Nov 22 '22 21:11

Marc Gravell