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

Error mocking internal members of Trimmable assemblies on Android #834

Open
jamescrosswell opened this issue Oct 22, 2024 · 4 comments
Open
Labels
feature-request Request for a new NSubstitute feature

Comments

@jamescrosswell
Copy link

jamescrosswell commented Oct 22, 2024

Describe the bug
Tests that use NSubstitute to mock internal members of Trimmable assemblies fail when run on Android, with the
following error:

System.ArgumentException : Can not create proxy for type Sentry.IPing because it is not accessible. Make it public, or internal and mark your assembly with [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] attribute, because assembly Sentry is strong-named. Arg_ParamName_Name, additionalInterfacesToProxy]]

If we set <IsTrimmable>false</IsTrimmable> in the .csproj file of the code being tested then the test pass.

To Reproduce

I've provided a minimal reproducable example at:

The readme.md file in that repo describes how to run the tests using the included powershell script.

Expected behaviour

We'd like the tests to pass for assemblies marked with IsTrimmable. With the growth of frameworks like MAUI we're seeing more and more people wanting to trim their applications.

Environment:

  • NSubstitute version: 5.1.0
  • NSubstitute.Analyzers version: CSharp 1.0.17
  • Platform: net8.0-android

Additional context
We bumped into this in the device tests for the Sentry SDK for .NET. For the time being, I'll look at disabling trimming on the relevant assemblies for the purposes of running these device tests. Ideally we'd be able to run our tests against the same code we ship though and we ship with <IsAotCompatible>true</IsAotCompatible> (so implicitly <IsTrimmable>true</IsTrimmable>).

@jamescrosswell jamescrosswell changed the title Error mocking internal members of Trimmable assemblies on iOS and Android Error mocking internal members of Trimmable assemblies on Android Oct 22, 2024
@dtchepak
Copy link
Member

Thanks for the report and repro @jamescrosswell. If this is being trimmed from the assembly then I'm not sure there is a lot we can do from the NSubstitute side? (Suggestions welcome! I'm not familiar with net8.0-android)

@304NotModified 304NotModified added the feature-request Request for a new NSubstitute feature label Oct 28, 2024
@304NotModified
Copy link
Contributor

Adding trimming support isn't trivial AFAIK. I'm tagging this as a feature request

@dtchepak
Copy link
Member

dtchepak commented Oct 28, 2024

A colleague that does some work with this mentioned they used specific excludes (although in the context of linking not testing). They sent me these references:

Not sure if that helps at all but figured I pass them along. 🙇

@jamescrosswell
Copy link
Author

jamescrosswell commented Oct 30, 2024

Adding trimming support isn't trivial AFAIK.

I think that's probably the reality... especially given the dependency on DynamicProxy which, as it's name suggests, is all about dynamic code generation.

The only solution that I can imagine is one that leverages Source Generators to create the mock objects, instead of using DynamicProxy. That would likely require a very different API for people to define the mocks though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request Request for a new NSubstitute feature
Projects
None yet
Development

No branches or pull requests

3 participants