-
-
Notifications
You must be signed in to change notification settings - Fork 804
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
MissingMethodException / "Method not found" after update to Moq 4.8.0 #566
Comments
Hi @JHotterbeekxBannerconnect and thanks for reporting. Unfortunately, I do not see anything related to Moq in your example code, so I have to wonder whether your issue is even related to Moq at all. Could you please provide a short but complete code example that demonstrates this issue, and shows how Moq is involved? (Otherwise I'll close this issue in a couple of days' time.) Thank you! (Btw. |
Hi, I think I'm seeing the same problem. Out of 405 tests using Moq, 16 started failing after upgrading to Moq 4.8.0 with exception "System.MissingMethodException: Method not found". It seems to be related to the "System.Net.Http" namespace since all the "missing methods" in the failing tests have types from that namespace in their signature (eg. "System.Net.Http.HttpResponseMessage"). |
@JHotterbeekxBannerconnect, @willykc: Could it be that you updated not just Moq, but any other Microsoft ASP.NET packages at the same time without noticing it? Because quite frankly, Moq has no dependency on, nor any special logic related to, any |
We've updated several packages, but saw tests failing. So I reverted everything and updated one by one, everything keeps working until the last package is updated, which is Moq. But I'm going to try cleaning old DLL's and cache and see what that does, and if it still doesn't work try a new solution to reproduce this. |
@JHotterbeekxBannerconnect: That's truly strange. Until you have repro code ready to share, could you perhaps give the following information:
|
@stakx I've been able to reproduce it in a simple test project: When you open this (in VS 2017) you'll see that there is one single test in there. This runs without any issues. Now try adding through NuGet, you'll see that the test fails. I've found something more interesting, when updating to the latest version of Moq through NuGet, another package seems to come along called System.Threading.Tasks.Extensions.4.4.0. This is the one that seems to be causing the error, because if I remove this as reference from the included test project, the test will succeed again. The other info you requested (for the test solution):
Hopefully this is enough for you to reproduce it. |
Thanks a lot for the test solution, and the analysis you've done already! I can now reproduce this issue. (One problem I noticed before I could even run your tests is that your project is a missing I'll now try to find the precise cause of this. |
OK, seems you're affected by the problem described in dotnet/standard#481, and adding the following to your <PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup> (PS: Alternatively, update your project file(s) to the new SDK format, which should already implicitly include the above properties.) The problem indeed gets triggered by Please see the issue referenced above for details. |
@stakx Thanks a lot for the help and explanation! I've added the properties to the solution and the tests run without any issue now. Seems like something that more people could run into, maybe this should be put in the wiki somewhere? |
@JHotterbeekxBannerconnect - I agree that this situation needs to be improved. I'm currently looking into Moq's reference of the Adding a warning to the wiki would be a start... would you like to do this? Short of temporarily removing I'm also still not sure yet why just referencing that assembly caused the issue (note that your test doesn't make use of it). |
@stakx I've added it as a FAQ to the wiki, referencing to the .net standard issue and this issue. Great that you'll look in to this, I agree that it feels weird that this issue is being caused, and even stranger without actually using anything from the reference. |
Hi @stakx, thanks a lot for the solution. After adding the property group to my test project file, all the failing tests are now passing. I'm not sure if this could help but an idea would be to add a .props file including the property group to the Moq NuGet package like so: https://docs.microsoft.com/en-us/nuget/create-packages/creating-a-package#including-msbuild-props-and-targets-in-a-package |
@stakx It seems that the adding of a .net standard reference was also causing issues on our TeamCity servers, which we had to resolve as well by updating the build tools and adding .net Core support. Just telling you because this could become an issue for more people. |
@JHotterbeekxBannerconnect, thanks a lot for setting up the FAQ! It's great to have such a resource that we can direct people to. 👍 @willykc, that's good to know—thanks for the link. However, I don't feel too comfortable about Moq influencing the build process behind the user's back. Moq is just a library and just one out of many possible dependencies a project might have. Imagine the potential complications if every dependency secretly modified your build. Some people might not actually want to have assembly binding redirects generated automatically. I believe the problem should be solved at the source, if possible. And I suspect it's that the build process picks the wrong assembly version from the If all else fails, I'm quite ready to temporarily remove I'll keep you updated! |
@stakx The System.Threading.Tasks.Extensions NuGet has a dependency on .Net Standard 1.0, the lowest common denominator. Microsoft's documentation on .Net Standard states that a 1.0 library is compatible with .Net Framework 4.5. Therefore, it shouldn't be a problem to have the net45 TFM reference the System.Threading.Tasks.Extensions NuGet. Visual Studio / NuGet.exe should pick up the "most correct" version of the NuGet when multiple targets are available. However, it is possible to only reference the NuGet on a specific TFM, and then #if out the relevant code if that's what you want. In fact, the Moq CSProj already does that. For what it's worth, I just tried the following sample code on a .Net 4.5 console app without any compilation, or runtime issues; using VS 2017 15.5.2. using Moq;
using System;
using System.Threading.Tasks;
namespace ConsoleApp1
{
public interface IFoo
{
ValueTask<string> Bar();
}
class Program
{
static async Task Main(string[] args)
{
Mock<IFoo> mock = new Mock<IFoo>();
mock.Setup(m => m.Bar()).ReturnsAsync("Hello world");
string bar = await mock.Object.Bar();
Console.WriteLine(bar);
}
}
} Does this answer your questions? PS. I definitely have felt the pain of .Net Standard in .Net Framework :( |
Let me summarize my findings regarding
(I originally wanted to include a rant about .NET Core, .NET Standard, and NuGet having put us back firmly in DLL hell, and about the continually sorry state of .NET tooling surrounding those three; but anyone working with .NET who hasn't lived under a rock in the past few years probably knows that already, so I've edited it out. 😜) 1. Test project that reproduces a
|
And finally... 🥁 4. What can be done at Moq's end?
I am open to suggestions how to resolve this in a better way. |
@stakx - I think for now your suggestion of wait and see a little longer probably best. The "holy grail" of .Net Standard sounded really cool until it all fell apart in actual use (in .Net Framework). System.Net.Http is probably the biggest offender, as you've found out. I can't find the war story that came to mind, but it was bad... A possible solution is to create a Moq.Extensions NuGet. Then treats like ValueTask can be opt in rather than everyone just gets it. |
@AdamDotNet, thanks for this feedback, it's much appreciated. Wait a little longer it is, then!
This is a pretty good idea! We just might do that if things don't get better soon. Thank you for suggesting it! (And, if you'd like to contribute by moving the offending bits into a separate package via a PR, please just let me know. I could signal you when the time's right.) |
@stakx - I could probably find time to create a new project in the Moq solution and move things over (a list of exactly what you want moved over would be appreciated, if more than just ValueTask). I'm not familiar with how you configure the build server script though. |
@AdamDotNet - Thanks for the kind offer. If it turns out that we actually need to do this in order to resolve the issue in a clean fashion, I'd be happy to guide you. Adding another project and |
@AdamDotNet: It has belatedly occurred to me that moving all but it wouldn't work in other cases such as here: without creating a module initializer (global static constructor) which C# does not support, so I fear an extension NuGet package is no way out of DLL hell. :-/ |
Did anyone submit a bug with System.Threading.Tasks.Extensions.4.4.0 to get a fix for this issue? Update: This workaround to manually edit the csproj to use the portalable library in the NuGet package worked for me.
|
If any one particular package is versioned incorrectly, it would likely be System.Net.Http. But the real problem isn't with any one specific package, IMHO, but the fact that .NET 4.6.1 has been changed retroactively to support and prefer .NET Standard 2.0 over portable libraries, thereby resulting in conflicts between framework DLLs and differently-versioned .NET Standard shim DLLs being copied over to your project's output directory.
See above: #566 (comment).
Glad you found a solution that works for you. But your manual changes will probably be overwritten next time you upgrade packages. |
I didn't think System.Net.Http was even a package involved, as it is not an installed NuGet package. However, taking into account .NET Standard shim DLLs, this makes sense. The System.Net.Http objects could be seen as completely different object in the shims.
Exactly why I want to follow this up. I would love for my manual changes to be overwritten AND the bug to be fixed and not notice this when the next version comes out. |
I understand. Unfortunately, there's not much we can do here at the Moq project other than fixing #578. I suggest you take this up directly with the .NET team. Like I said above, please see the issue I linked to in the comment above (dotnet/standard#481). To be very honest with you, I am really quite fed up with (and burned out a little due to) the .NET assembly versioning mess that's been going on for the past few years, so please don't count on my support. :-/ I sincerely do hope, however, that if you follow up on this, that you'll be successful in getting this through to Microsoft. |
Further to this: I am receiving this problem with a project in new csproj format targeting net461. Although not required, I tried it with and without the workaround adding properties Since we have 50+ projects with test in them switching mocking frameworks would be an expensive/risky exercise which obviously we would like to avoid. Anyone has any other suggestion for what we could try to resolve this issue? Update: We were using Moq to mock |
Did you go back to System.Threading.Tasks.Extensions.4.3.0 and make sure it is using the dll from the portable-net45+win8+wp8+wpa81 folder? Also, just FYI, I minimized the bug, taking Moq out of the picture. The bug I submitted on this to the dotnet project was added to Milestone 5. https://github.com/dotnet/corefx/issues/27907 |
@rhyous Thank you for the suggestion. We found a work around. We were using Moq to mock HttpResponseBase, HttpRequestBase and HttpContextBase. We now have our own explicit mocks in place for these. We have almost 60 projects in our solution so going back and forth between different versions of 3rd party libraries has its limitations both technically and time wise. We appreciate that it seems to a be an issue within dotnet and unrelated to Moq. In our case it appeared when we upgraded Moq. We acknowledge that it's not caused by Moq. We continue to use Moq for almost all our mocking needs, so please keep up the excellent work on this project. Thank you! |
@ManfredLange - Thanks for the kind words. May I suggest that you watch #605 (or rather, look out for the future Moq version where this particular issue will be resolved) if you're still interested in seeing this resolved? It's likely that due to that issue, we'll soon add .NET Standard 2.0 as a framework target to the Moq NuGet package. I haven't carved out an exact plan yet, but adding direct support for .NET Standard 2.0 will likely mean, among other things, less NuGet package dependencies. If we update Moq's dependency on System.Threading.Tasks.Extensions to package version 4.4.0, then Moq should no longer bring in the System.Net.Http package via System.Runtime into your projects. I'm not sure if it'll work out like that in your case (you might have to update the problematic unit test projects to .NET 4.7), but it's perhaps worth a try. (Perhaps, if you still have enough patience left to deal with this at all 😉, you could try the following already now: Upgrade the problematic unit test projects to .NET 4.7, and explicitly bring in the System.Threading.Tasks.Extensions package and pin that dependency at version 4.4.0. Afterward, bring in Moq 4.8.2. You might then need an assembly version redirect for STTE because Moq expects version 4.3.0.) |
@stakx We are migrating our projects across from net461 to netstandard2.0 / netcoreapp2.0 at the moment. For that process we believe that going to .NET 4.7, then to netstandard2.0 would be more of a sidetrack. We are happy to continue use Moq. We always knew that mocking HttpRequestBase, HttpResponseBase and HttpContextBase could be a stretch. And mocking of these classes will change with ASP.NET Core MVC again as far as we know. We are definitely looking forward to netstandard2.0 support for Moq. :-) |
I see this is a very long thread and apologies I didn't read every single post, but I have just been bitten with what appears to be the same issue upgrading from 4.7.145.0 to 4.8.0.0, although getting a different error when running some unit tests:
This is in a .Net Framework 4.5 assembly and is fixed by reverting back to 4.7.145.0 and removing the I know Moq is a community project but it would be nice if this breaking change had been made into a major version update so we could be a bit more confident that a minor release won't break our projects. |
Given that this repository's name pretty much sets the major version in stone, I wouldn't have increased the major version for this anyway, not even with the benefit of hindsight: Adding a NuGet dependency to support a relatively minor new feature isn't a breaking change per se. Prior to releasing Moq 4.8.0, there was no indication whatsoever that this would cause any issues for people. (Note btw. that there was a release candidate for 4.8.0. Perhaps we should have given it much more time before releasing 4.8.0 proper, but at the time I thought this pointless given the very low number of downloads and the fact that the RC generated no feedback whatsoever.) I've said it before, and I'll say it one more time: The problem you're seeing isn't specific to Moq. There isn't anything wrong with Moq 4.8.x. per se. The problems we're having here are rather more general tooling-related issues with .NET (more precisely, with the way how NuGet and MSBuild pick the "right" package and assembly versions). With the advent of .NET Standard, it has become possible for MSBuild to have to choose between more than one suitable assembly from those offered by a multi-targeting NuGet package. And depending on how your project is set up (target framework(s), preexisting assembly version redirects, project file format, certain MSBuild properties, etc.), MSBuild sometimes makes the wrong choice. I'm sorry to see that this is causing Moq users some trouble, but there's simply no realistic way for Moq (or any other open-source project of comparable size) that I can see to anticipate all the possible project setups and dependencies that are out there. What needs to happen is that (1) Microsoft must continue to fix their tools to get us all out of the versioning hell .NET currently finds itself in. (VS 2017, .NET 4.7, .NET Core 2.0, and .NET Standard 2.0 are getting close to that, I think.) (2) People need to adopt these new .NET and tool versions. While that hasn't happened, (3) everyone who's affected must learn about .NET assembly versioning and how to fix versioning conflicts in their own projects. |
First off, I totally get this is not a fault with Moq! Secondly, I want to say thanks for Moq, it is wonderful. I've read every message here and #567 and I'm unable to workaround the issue. My test project is on framework 4.7.0. This came up when upgrading to Moq 4.8.2. (I know everyone who carefully reads all the messages already knows the basic scenario but explicit details are oh-so-important in case I'm missing something) We are using packages.config and have not moved to PackageReference yet (waiting on VS 15.7 for the migration option). There is so much noise I just want to recap the exception as well:
The referenced System.Threading.Tasks.Extensions nuget package is 4.1.1.0. The AssemblyVersion of the actual referenced dll is 4.1.1.0 (verified with JustDecompile). As @stakx has so clearly pointed out several times, the issue stems from MSBuild preferring the .netstandard2.0 assembly over the PCL/net45 assembly. @rhyous mentioned that he manually edited the project file to point to the PCL specific assembly so I tried that as well by changing that reference to portable-net45+win8+wp8+wpa81. This did not work for me either and I realize that change will get paved over when upgrading that nuget package later. Just wanted to explain that didn't work for me either. I've tried adding the following to my test project csproj: So I've tried .NET Framework 4.7.2, AutoGenerateBindingRedirects and GenerateBindingRedirectsOutputType, manually pointing the assembly reference in the project file to use the PCL version and all kinds of binding redirect version number changes. I'm afraid I will have to downgrade to Moq 4.7.145 but I want to understand the problem well enough to solve it. |
@AdamCaviness - people keep having problems with this... and I almost can't quite believe that tooling is indeed so broken that there's no way at all to work around this. Would it be possible for you to submit a small test project (e.g. as a ZIP file) for me to look at? |
@stakx Because our solutions are so large I should have started with a sample project really. As I began to consider the requirements for a sample project I discovered that one of my three lower-level test projects had no app.config file and hence no binding redirects. This of course sorted it out. For the curious, I was able to keep all the project references to the assemblies pointing to netstandard2.0 instead of portable-net45+win8+wp8+wpa81. I was also able to keep my framework version at 4.7 and I didn't need 4.7.2. |
@AdamCaviness - great to hear you were able to sort things out! |
We are having same issue with 4.8.3 on .net 4.6.2, have to downgrade to 4.7.145. |
@skram-softheme ... or resolve the version conflict. It's usually very much possible. 😉 |
We solved the problem in TeamCity setting the advance setting Path to application configuration file: The config file contains the binding redirect:
|
For anyone encountering this issue in 2019. The tests ran successfully (green) on our development environment. However, they failed on the build server with
Adding the Binding nodes to the PropertyGroup didn't work for me. I ended up updating System.Threading.Tasks.Extensions separately. The tests are now green on our build server as well. |
hi @DianaKoenraadt, could you elaborate on how you did that? |
Seems to fix it |
Im Using PackageReference Include="Moq" Version="4.13.1" and still encounter this problem |
…ding explicitly the binding redirects intended to be automated by package Microsoft.NET.Test.Sdk. See: devlooped/moq#566 (comment) dotnet/standard#481
…ding explicitly the binding redirects intended to be automated by package Microsoft.NET.Test.Sdk. See: devlooped/moq#566 (comment) dotnet/standard#481
Hi,
Today I've tried updating the NuGet package from 4.7.145.0 to 4.8.0.0 and I'm running into an issue with a specific test case failing now on a strange error message. To give you some context, in our tests we create a HttpActionContext to test our authentication. This is native .net functionality. I've isolated the issue to the following code:
When running this test, it fails with the following error:
Could you help me figure out what is wrong, or fix this if it is an actual bug?
Thanks,
John
The text was updated successfully, but these errors were encountered: