Skip to content

[Bug]: TUnit.Mocks emits trim/AOT warnings on Native AOT publish #7027

Closed

Description

@fubar-coder

Bug report checklist

  • I've searched existing issues to ensure this isn't a duplicate
  • I've read the documentation and this isn't expected behavior
  • I'm using the latest version of TUnit

Description

When publishing a test project that uses TUnit.Mocks with PublishAot=true, ILC reports warnings coming from TUnit.Mocks, even if no custom IDefaultValueProvider or generic mock is used. The tests pass as a native executable, but with TreatWarningsAsErrors the publish fails.

As far as I can tell, MockEngine.HandleCallWithReturn and MockRegistry.CreateClosedGenericMock suppress the warnings with #pragma warning disable, which only affects the Roslyn analyzer, not ILC. Using [UnconditionalSuppressMessage] instead (and [RequiresUnreferencedCode]/[RequiresDynamicCode] on the APIs that set a default value provider) should fix it.

Mocking a generic interface additionally causes IL2069, because OpenGenericFactoryDescriptor only annotates its members with [property: DynamicallyAccessedMembers(...)]. The constructor parameters also need [param: ...].

Expected Behavior

No trim/AOT warnings when using basic mocks (Mock.Of<T>(), Returns, WasCalled).

Actual Behavior

IL2026, IL2055 and 2× IL3050 for a basic mock; 2× IL2069 more for a generic interface mock.

Steps to Reproduce

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <OutputType>Exe</OutputType>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <PublishAot>true</PublishAot>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="TUnit" Version="1.73.19" />
    <PackageReference Include="TUnit.Mocks" Version="1.73.19" />
  </ItemGroup>
</Project>
using TUnit.Mocks;

public interface ICalculator { int Add(int a, int b); }
public interface IRepository<T> { T? Find(int id); }

public class MockTests
{
    [Test]
    public async Task Basic()
    {
        var mock = Mock.Of<ICalculator>();
        mock.Add(1, 2).Returns(3);
        await Assert.That(mock.Object.Add(1, 2)).IsEqualTo(3);
    }

    [Test]
    public async Task Generic() // causes the IL2069 warnings
    {
        var mock = Mock.Of<IRepository<string>>();
        mock.Find(1).Returns("one");
        await Assert.That(mock.Object.Find(1)).IsEqualTo("one");
    }
}

dotnet publish -c Release -r linux-x64 -p:TrimmerSingleWarn=false

TUnit Version

1.73.19

.NET Version

.NET 10 (SDK 10.0.401), .NET 11 RC1

Operating System

Linux

IDE / Test Runner

dotnet CLI (dotnet test / dotnet run)

Error Output / Stack Trace

Generating native code
ILC : Trim analysis warning IL2069: TUnit.Mocks.MockRegistry.OpenGenericFactoryDescriptor.OpenGenericFactoryDescriptor(Type,Type): value stored in field 'TUnit.Mocks.MockRegistry.OpenGenericFactoryDescriptor.<OpenImplementationType>k__BackingField' does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors', 'DynamicallyAccessedMemberTypes.NonPublicConstructors' requirements. The parameter 'OpenImplementationType' of method 'TUnit.Mocks.MockRegistry.OpenGenericFactoryDescriptor.OpenGenericFactoryDescriptor(Type,Type)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/home/fubar-coder/Projekte/Tests/TrimTestWarnings/test.csproj]
ILC : Trim analysis warning IL2069: TUnit.Mocks.MockRegistry.OpenGenericFactoryDescriptor.OpenGenericFactoryDescriptor(Type,Type): value stored in field 'TUnit.Mocks.MockRegistry.OpenGenericFactoryDescriptor.<OpenWrapperType>k__BackingField' does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors', 'DynamicallyAccessedMemberTypes.NonPublicConstructors' requirements. The parameter 'OpenWrapperType' of method 'TUnit.Mocks.MockRegistry.OpenGenericFactoryDescriptor.OpenGenericFactoryDescriptor(Type,Type)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/home/fubar-coder/Projekte/Tests/TrimTestWarnings/test.csproj]
ILC : Trim analysis warning IL2026: TUnit.Mocks.MockEngine`1.HandleCallWithReturn<TReturn,T1>(Int32,String,T1,!!0): Using member 'TUnit.Mocks.IDefaultValueProvider.GetDefaultValue(Type)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Implementations may use reflection to construct types at runtime. [/home/fubar-coder/Projekte/Tests/TrimTestWarnings/test.csproj]
ILC : AOT analysis warning IL3050: TUnit.Mocks.MockEngine`1.HandleCallWithReturn<TReturn,T1>(Int32,String,T1,!!0): Using member 'TUnit.Mocks.IDefaultValueProvider.GetDefaultValue(Type)' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. Implementations may use MakeGenericMethod or Activator.CreateInstance. AOT-safe implementations can override without these. [/home/fubar-coder/Projekte/Tests/TrimTestWarnings/test.csproj]
ILC : Trim analysis warning IL2026: TUnit.Mocks.MockEngine`1.HandleCallWithReturn<TReturn,T1,T2>(Int32,String,T1,T2,!!0): Using member 'TUnit.Mocks.IDefaultValueProvider.GetDefaultValue(Type)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Implementations may use reflection to construct types at runtime. [/home/fubar-coder/Projekte/Tests/TrimTestWarnings/test.csproj]
ILC : AOT analysis warning IL3050: TUnit.Mocks.MockEngine`1.HandleCallWithReturn<TReturn,T1,T2>(Int32,String,T1,T2,!!0): Using member 'TUnit.Mocks.IDefaultValueProvider.GetDefaultValue(Type)' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. Implementations may use MakeGenericMethod or Activator.CreateInstance. AOT-safe implementations can override without these. [/home/fubar-coder/Projekte/Tests/TrimTestWarnings/test.csproj]
ILC : AOT analysis warning IL3050: TUnit.Mocks.MockRegistry.CreateClosedGenericMock(Type,MockBehavior,Object[],MockRegistry.OpenGenericFactoryDescriptor): Using member 'System.Type.MakeGenericType(Type[])' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. The native code for this instantiation might not be available at runtime. [/home/fubar-coder/Projekte/Tests/TrimTestWarnings/test.csproj]
ILC : Trim analysis warning IL2055: TUnit.Mocks.MockRegistry.CreateClosedGenericMock(Type,MockBehavior,Object[],MockRegistry.OpenGenericFactoryDescriptor): Call to 'System.Type.MakeGenericType(Type[])' can not be statically analyzed. It's not possible to guarantee the availability of requirements of the generic type. [/home/fubar-coder/Projekte/Tests/TrimTestWarnings/test.csproj]
ILC : AOT analysis warning IL3050: TUnit.Mocks.MockRegistry.CreateClosedGenericMock(Type,MockBehavior,Object[],MockRegistry.OpenGenericFactoryDescriptor): Using member 'System.Type.MakeGenericType(Type[])' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. The native code for this instantiation might not be available at runtime. [/home/fubar-coder/Projekte/Tests/TrimTestWarnings/test.csproj]
ILC : Trim analysis warning IL2055: TUnit.Mocks.MockRegistry.CreateClosedGenericMock(Type,MockBehavior,Object[],MockRegistry.OpenGenericFactoryDescriptor): Call to 'System.Type.MakeGenericType(Type[])' can not be statically analyzed. It's not possible to guarantee the availability of requirements of the generic type. [/home/fubar-coder/Projekte/Tests/TrimTestWarnings/test.csproj]

Simpler excerpt:

IL3050: TUnit.Mocks.MockEngine`1.HandleCallWithReturn<TReturn,T1,T2>(...): Using member 'TUnit.Mocks.IDefaultValueProvider.GetDefaultValue(Type)' which has 'RequiresDynamicCodeAttribute' ...
IL2026: TUnit.Mocks.MockEngine`1.HandleCallWithReturn<TReturn,T1,T2>(...): Using member 'TUnit.Mocks.IDefaultValueProvider.GetDefaultValue(Type)' which has 'RequiresUnreferencedCodeAttribute' ...
IL3050: TUnit.Mocks.MockRegistry.CreateClosedGenericMock(...): Using member 'System.Type.MakeGenericType(Type[])' which has 'RequiresDynamicCodeAttribute' ...
IL2055: TUnit.Mocks.MockRegistry.CreateClosedGenericMock(...): Call to 'System.Type.MakeGenericType(Type[])' can not be statically analyzed ...
IL2069: TUnit.Mocks.MockRegistry.OpenGenericFactoryDescriptor.OpenGenericFactoryDescriptor(Type,Type): value stored in field '<OpenImplementationType>k__BackingField' does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors', 'DynamicallyAccessedMemberTypes.NonPublicConstructors' requirements ...
IL2069: (same for '<OpenWrapperType>k__BackingField')

Additional Context

Yes, Native AOT. For now we downgrade these warnings in our test projects with WarningsNotAsErrors.

IDE-Specific Issue?

  • I've confirmed this issue occurs when running via dotnet test or dotnet run, not just in my IDE

Activity

  1. added a commit that references this issue on Oct 11, 2026
    81c587c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions