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

System.NotSupportedException : Cannot create boxed ByRef-like values. #829

Closed
tonyranieri opened this issue May 14, 2019 · 2 comments
Closed

Comments

@tonyranieri
Copy link

Trying to test code that uses a service that returns ReadOnlySpan<char> doesn't seem possible.

Using Moq Version 4.10.1

I've created a repo that reproduces the issue - https://github.com/wessiyad/moq-readonlyspan-issue

PS C:\source\poc\moq-ros-issue\src> dotnet test
Skipping running test for project C:\source\poc\moq-ros-issue\src\WebSample\WebSample.csproj. To run tests with dotnet test add "<IsTestProject>true<IsTestProject>" property to project file.
Build started, please wait...
Build completed.

Test run for C:\source\poc\moq-ros-issue\src\Test\bin\Debug\netcoreapp2.2\Test.dll(.NETCoreApp,Version=v2.2)
Microsoft (R) Test Execution Command Line Tool Version 15.9.0
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...
[xUnit.net 00:00:01.09]     Test.ValuesControllerTest.Fails_At_Runtime [FAIL]
Failed   Test.ValuesControllerTest.Fails_At_Runtime
Error Message:
 System.NotSupportedException : Cannot create boxed ByRef-like values.
Stack Trace:
   at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean wrapExceptions, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor)
   at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean wrapExceptions, Boolean skipCheckThis, Boolean fillCache)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic, Boolean wrapExceptions)
   at Moq.LookupOrFallbackDefaultValueProvider.GetDefaultValue(Type type, Mock mock) in C:\projects\moq4\src\Moq\LookupOrFallbackDefaultValueProvider.cs:line 127
   at Moq.Mock.GetDefaultValue(MethodInfo method, DefaultValueProvider useAlternateProvider) in C:\projects\moq4\src\Moq\Mock.cs:line 909
   at Moq.Return.Handle(Invocation invocation, Mock mock) in C:\projects\moq4\src\Moq\Interception\InterceptionAspects.cs:line 343
   at Moq.Mock.Moq.IInterceptor.Intercept(Invocation invocation) in C:\projects\moq4\src\Moq\Interception\Mock.cs:line 20
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at Castle.Proxies.IFooServiceProxy.GetSomeData()
   at WebSample.Controllers.ValuesController.Get() in C:\source\poc\moq-ros-issue\src\WebSample\Controllers\ValuesController.cs:line 25
   at Test.ValuesControllerTest.Fails_At_Runtime() in C:\source\poc\moq-ros-issue\src\Test\ValuesControllerTest.cs:line 17

Total tests: 1. Passed: 0. Failed: 1. Skipped: 0.
Test Run Failed.
Test execution time: 2.1398 Seconds
.NET Core SDK (reflecting any global.json):
 Version:   2.2.203
 Commit:    e5bab63eca

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.14393
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\2.2.203\

Host (useful for support):
  Version: 2.2.4
  Commit:  f95848e524

.NET Core SDKs installed:
  1.0.0 [C:\Program Files\dotnet\sdk]
  1.0.1 [C:\Program Files\dotnet\sdk]
  1.0.4 [C:\Program Files\dotnet\sdk]
  2.0.0 [C:\Program Files\dotnet\sdk]
  2.0.2 [C:\Program Files\dotnet\sdk]
  2.1.4 [C:\Program Files\dotnet\sdk]
  2.1.300 [C:\Program Files\dotnet\sdk]
  2.1.302 [C:\Program Files\dotnet\sdk]
  2.2.104 [C:\Program Files\dotnet\sdk]
  2.2.203 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.2.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.2.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.2.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.2.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 1.0.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 1.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 1.1.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 1.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.2.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.2.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]

Expected outcome is that I'm able to mock the method. When I discovered this I was simply trying to verify if the method was called or not, but I could see more involved testing where the result is returned as well.

Let me know if you need more details! 😀

@stakx
Copy link
Contributor

stakx commented May 15, 2019

Hi @wessiyad, thanks for reporting. At first glance, it looks like this is a limitation of Activator.CreateInstance, meaning that there is probably nothing we can do inside Moq to get this use case working.

@stakx
Copy link
Contributor

stakx commented May 15, 2019

Indeed, your repro code can be shortened to the following one-liner:

_ = Activator.CreateInstance(typeof(ReadOnlySpan<char>));

And I'm sorry to say that there's nothing we can do to work around this runtime / framework limitation. Moq won't be able to create a default return value for your interface method due to that.

ReadOnlySpan<T> is a ref struct (i.e. a stack-only type) and therefore cannot be boxed (i.e. wrapped in an object that lives on the heap), which would have to happen because Activator.CreateInstance (like many other reflection facilities) returns an object.

@stakx stakx closed this as completed May 15, 2019
dougbu added a commit to dougbu/AspNetWebStack that referenced this issue Feb 2, 2023
- expand our text matrix to include a modern (and LTS) TFM
- move to VS2022 and the latest 6.0 .NET SDK for `net6.0` support
- change how Formatting test assemblies are found
  - `netcoreapp` is no longer the only relevant folder prefix
- react to new `Exception.Message`s in `netcoreapp3.1`
  - handle different formatting of argument info in `ArgumentException.Message`s
  - handle slightly greater `decimal` precision in a `JsonReaderException.Message`
- react to new `Exception.Message`s and other changes in `net6.0`
  - handle different `Message` in `InvalidOperationException`s about invalid request URIs
  - handle `HttpResponseMessage.Content != null` after construction (a test-only change fortunately)
    - see dotnet/runtime@b48900f which introduced this
  - handle inability to mock a `Stream` if a writer passes a `ReadOnlySpan<byte>` in `net6.0`
    - see devlooped/moq#829, devlooped/moq#979, and dotnet/runtime#45152 about the issue
- nit: simplify define use now that `NETCOREAPP3_1_OR_GREATER` and so on are available
dougbu added a commit to dougbu/AspNetWebStack that referenced this issue Feb 11, 2023
- expand our text matrix to include a modern (and LTS) TFM
- change how Formatting test assemblies are found
  - `netcoreapp` is no longer the only relevant folder prefix
- use the latest .NET 6 SDK
  - install the 2.1.x runtime in the pipeline
- don't require .NET in VS
  - will use binplaced `msbuild` instead
  - have `git` ignore the new .msbuild/ folder
- react to new `Exception.Message`s in `netcoreapp3.1`
  - handle different formatting of argument info in `ArgumentException.Message`s
  - handle slightly greater `decimal` precision in a `JsonReaderException.Message`
- react to new `Exception.Message`s and other changes in `net6.0`
  - handle different `Message` in `InvalidOperationException`s about invalid request URIs
- react to other changes in `net6.0`
  - handle inability to mock a `Stream` if a writer passes a `ReadOnlySpan<byte>` in `net6.0`
    - see devlooped/moq#829, devlooped/moq#979, and dotnet/runtime#45152 about the issue
  - skip tests failing due to `HttpResponseMessage` changes
    - see dotnet/runtime@b48900f which introduced this
- nits:
  - simplify define use now that `NETCOREAPP3_1_OR_GREATER` and so on are available
  - clean up .gitignore
dougbu added a commit to aspnet/AspNetWebStack that referenced this issue Feb 13, 2023
- expand our text matrix to include a modern (and LTS) TFM
- change how Formatting test assemblies are found
  - `netcoreapp` is no longer the only relevant folder prefix
- use the latest .NET 6 SDK
  - install the 2.1.x runtime in the pipeline
- don't require .NET in VS
  - will use binplaced `msbuild` instead
  - have `git` ignore the new .msbuild/ folder
- react to new `Exception.Message`s in `netcoreapp3.1`
  - handle different formatting of argument info in `ArgumentException.Message`s
  - handle slightly greater `decimal` precision in a `JsonReaderException.Message`
- react to new `Exception.Message`s and other changes in `net6.0`
  - handle different `Message` in `InvalidOperationException`s about invalid request URIs
- react to other changes in `net6.0`
  - handle inability to mock a `Stream` if a writer passes a `ReadOnlySpan<byte>` in `net6.0`
    - see devlooped/moq#829, devlooped/moq#979, and dotnet/runtime#45152 about the issue
  - skip tests failing due to `HttpResponseMessage` changes
    - see #386 and dotnet/runtime@b48900f (which introduced this)
    - fix coming **Real Soon Now:tm:** :grin:
- nits:
  - simplify define use now that `NETCOREAPP3_1_OR_GREATER` and so on are available
  - clean up .gitignore
  - clean up a few comments and tighten scripting up
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

2 participants