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.MissingMethodException Method not found: 'Boolean Castle.DynamicProxy.ProxyUtil.IsAccessible()' #308

Closed
smithkl42 opened this issue Sep 30, 2017 · 24 comments

Comments

@smithkl42
Copy link

After upgrading to Castle 4.2.0, I'm getting a System.MissingMethodException with Moq 4.7.127 when trying to run some unit tests.

System.MissingMethodException
Method not found: 'Boolean Castle.DynamicProxy.ProxyUtil.IsAccessible(System.Reflection.MethodBase, System.String ByRef)'.
   at Moq.Proxy.CastleProxyFactory.IsMethodVisible(MethodInfo method, String& messageIfNotVisible)
   at Moq.Mock.ThrowIfSetupMethodNotVisibleToProxyFactory(MethodInfo method) in C:\projects\moq4\Source\Mock.cs:line 811
   at Moq.Mock.<>c__DisplayClass63_0`2.<Setup>b__0() in C:\projects\moq4\Source\Mock.cs:line 469
   at Swyfft.Services.Tests.UnitTestBase..ctor() in C:\source\Swyfft\Swyfft.Services.Tests\UnitTestBase.cs:line 44
   at Swyfft.Services.Tests.ReplacementCost.BatchReplacementCostServiceUnitTests..ctor() in C:\source\Swyfft\Swyfft.Services.Tests\ReplacementCost\BatchReplacementCostServiceUnitTests.cs:line 31

Downgrading to 4.1.1 solves the issue.

It sounds like Castle has updated a few things in 4.2 - is this a breaking change that Moq needs to update for?

@stakx
Copy link
Member

stakx commented Sep 30, 2017

@smithkl42 - thanks for reporting this. I'd say this is an issue with Moq, not with Castle Core. I would expect this problem to go away if you update to Moq 4.7.137 (which references Castle.Core 4.2.0)... could you please try this first?

I was involved in #290 which likely led up to this situation. We juggled around a few methods related to the one that's now gone "missing", but we did take care to keep method signatures intact. ProxyUtil.IsAccessible was there before (in 4.1.1), and it's still there now (in 4.2.0), with its signature unchanged. I figured that would be enough to keep binary compatibility.

I'm speculating now, but perhaps this MissingMethodException is caused by a change not to the method itself, but to its containing type: ProxyUtil class became static in 4.2.0 (we discussed this, too). I've run a few experiments though, and I can't confirm that this change would cause problems... but it's my best guess right now.

I will see that Moq gets an update ASAP (Moq 4.7.137 is available now); perhaps in the meantime, @jonorossi or @fir3pho3nixx can confirm my above speculation, or offer a different (better) explanation.

@jonorossi
Copy link
Member

@stakx I agree, changing the class to static appears to be the only thing we changed that I would think could have caused it.

The IL of Castle.Core 4.1.1 vs 4.2.0 does change by specifying the class as static:

-.class public          auto ansi        beforefieldinit Castle.DynamicProxy.ProxyUtil extends [mscorlib]System.Object
+.class public abstract auto ansi sealed beforefieldinit Castle.DynamicProxy.ProxyUtil extends [mscorlib]System.Object

However, as expected the calling code in Moq 4.7.127 is the same as 4.7.137:

.method public hidebysig newslot virtual final 
        instance bool  IsMethodVisible(class [mscorlib]System.Reflection.MethodInfo 'method',
                                       [out] string& messageIfNotVisible) cil managed
{
  .maxstack  8
  IL_0000:  ldarg.1
  IL_0001:  ldarg.2
  IL_0002:  call bool [Castle.Core]Castle.DynamicProxy.ProxyUtil::IsAccessible(class [mscorlib]System.Reflection.MethodBase, string&)
  IL_0007:  ret
}

@smithkl42 can you confirm the version number of Castle.Core.dll is 4.2.0, and not a previous version without this method.

@stakx
Copy link
Member

stakx commented Oct 5, 2017

(@jonorossi: FWIW, I checked with ECMA-335: A TypeRef metadata table entry--which is what a Moq 4.7.127 assembly contains for Castle's ProxyUtil class--does not carry any details about the referenced type other than its resolution scope, namespace, and name. In other words, a compiled Moq.dll won't have any expectation about ProxyUtil being static or otherwise, therefore us having turned that class static is unlikely to have caused the present issue.)

@smithkl42
Copy link
Author

What I just confirmed again:

  • With Castle 4.1.1 and Moq 4.7.127: Our tests work.
  • With Castle 4.2.0 and Moq 4.7.127: Our tests break (with the error above).
  • With Castle 4.2.0 and Moq 4.7.137: Our tests work.

So I'm not sure why Moq 4.7.137 fixes things, but it definitely seems to.

@stakx
Copy link
Member

stakx commented Oct 6, 2017

@smithkl42: Could you please (a) state what platform (including version) your code is targeting (.NET Framework, .NET Core, Mono, etc.), and (b) post repro code?

Even if the problem appears to be fixed with the new versions it'd be good to find out how it got caused, so we can try to prevent it from happening again.

@jonorossi
Copy link
Member

Even if the problem appears to be fixed with the new versions it'd be good to find out how it got caused, so we can try to prevent it from happening again.

Agreed, I'd really like to avoid making a breaking change like this in the future. Really not sure where to look next to work out what is going on: v4.1.1...v4.2.0

@stakx
Copy link
Member

stakx commented Oct 9, 2017

@jonorossi - The only other thing that I can think of is that somehow, NuGet resolved the wrong platform DLLs. Just today I observed VS 2017 pick .NET 4.6.1 assemblies of xUnit for a .NET Core 2.0 console app project.

.NET Standard has MethodBase in a System.Reflection.dll reference assembly (distributed via NuGet), while .NET Framework has it in mscorlib.dll (IIRC), so method signatures could mismatch based on that. This would obviously be more of a tooling issue rather than Moq or Castle Core being broken.

If this happened to @smithkl42, he would likely see a NuGet warning (possibly NU1701) in VS' output window.

What I find somewhat implausible about this is that there wouldn't be an earlier call from Moq to Castle Core (before ProxyUtil.IsAccessible) that would trigger a similar problem. But without a closer look at Moq call sequences, I'd say it's a possibility.

@sbdevman
Copy link

sbdevman commented Oct 10, 2017

Hi,
I have same problem but for my case it is not any problem in my local workspace but when I run TFS build and run test during build this problem show itself

Copyright (c) Microsoft Corporation.  All rights reserved.
Starting test execution, please wait...
Information: [xUnit.net 00:00:14.7869686]   Discovering: Banking.LoanManagement.Domain.Tests (app domain = on [shadow copy], method display = ClassAndMethod)
Information: [xUnit.net 00:00:15.6009641]   Discovered:  Banking.LoanManagement.Domain.Tests (running 3 test cases)
Information: [xUnit.net 00:00:15.6154367]   Starting:    Banking.LoanManagement.Domain.Tests (parallel test collections = on, max threads = 8)
Information: [xUnit.net 00:00:17.7961534]   Finished:    Banking.LoanManagement.Domain.Tests
Passed   Banking.LoanManagement.Domain.Tests.Loan.LoanTests.Loan_should_be_created_with_default_parameters
Passed   Banking.LoanManagement.Domain.Tests.Loan.LoanTests.Loan_should_be_cancelled_with_default_parameters
Passed   Banking.LoanManagement.Domain.Tests.Loan.LoanTests.Loan_should_be_approved_with_default_parameters
Information: [xUnit.net 00:00:21.5900689]   Discovering: Banking.LoanManagement.Domain.Tests
Information: [xUnit.net 00:00:21.7893103]   Discovered:  Banking.LoanManagement.Domain.Tests
Information: [xUnit.net 00:00:21.7906212]   Starting:    Banking.LoanManagement.Domain.Tests
Error: [xUnit.net 00:00:22.7236865] Banking.LoanManagement.Domain.Tests.Loan.LoanTests.Loan_should_be_created_with_default_parameters [FAIL]
Information: [xUnit.net 00:00:22.7430500]       System.AggregateException : One or more errors occurred.
Information: [xUnit.net 00:00:22.7440540]       ---- System.MissingMethodException : Method not found: 'Boolean Castle.DynamicProxy.ProxyUtil.IsAccessible(System.Reflection.MethodBase, System.String ByRef)'.
Information: [xUnit.net 00:00:22.7449570]       ---- The following constructor parameters did not have matching fixture data: LoanFixture fixture
Information: [xUnit.net 00:00:22.7576882]       Stack Trace:
Information: [xUnit.net 00:00:22.7595283]         
Information: [xUnit.net 00:00:22.7604381]         ----- Inner Stack Trace #1 (System.MissingMethodException) -----
Information: [xUnit.net 00:00:22.7612945]            at Moq.Proxy.CastleProxyFactory.IsMethodVisible(MethodInfo method, String& messageIfNotVisible)
Information: [xUnit.net 00:00:22.7623139]         C:\projects\moq4\Source\Mock.cs(811,0): at Moq.Mock.ThrowIfSetupMethodNotVisibleToProxyFactory(MethodInfo method)
Information: [xUnit.net 00:00:22.7631600]         C:\projects\moq4\Source\Mock.cs(439,0): at Moq.Mock.<>c__DisplayClass62_0`1.<Setup>b__0()
Information: [xUnit.net 00:00:22.7640013]         C:\projects\moq4\Source\PexProtector.cs(61,0): at Moq.PexProtector.Invoke[T](Func`1 function)
Information: [xUnit.net 00:00:22.7648574]         C:\projects\moq4\Source\Mock.cs(432,0): at Moq.Mock.Setup[T](Mock`1 mock, Expression`1 expression, Condition condition)
Information: [xUnit.net 00:00:22.7657161]         C:\projects\moq4\Source\Mock.Generic.cs(263,0): at Moq.Mock`1.Setup(Expression`1 expression)
Information: [xUnit.net 00:00:22.7665289]         s\Sekhavat\Banking\Banking.LoanManagement.Domain.Tests\Core\LoanFixture.cs(98,0): at Banking.LoanManagement.Domain.Tests.Core.LoanFixture.Initialize()
Information: [xUnit.net 00:00:22.7673481]         s\Sekhavat\Banking\Banking.LoanManagement.Domain.Tests\Core\LoanFixture.cs(36,0): at Banking.LoanManagement.Domain.Tests.Core.LoanFixture..ctor()
Information: [xUnit.net 00:00:22.7681174]         ----- Inner Stack Trace #2 (Xunit.Sdk.TestClassException) -----
Information: [xUnit.net 00:00:22.7689231]         
Error: [xUnit.net 00:00:22.8321672] Banking.LoanManagement.Domain.Tests.Loan.LoanTests.Loan_should_be_cancelled_with_default_parameters [FAIL]
Information: [xUnit.net 00:00:22.8448542]       System.AggregateException : One or more errors occurred.
Information: [xUnit.net 00:00:22.8457824]       ---- System.MissingMethodException : Method not found: 'Boolean Castle.DynamicProxy.ProxyUtil.IsAccessible(System.Reflection.MethodBase, System.String ByRef)'.
Information: [xUnit.net 00:00:22.8466110]       ---- The following constructor parameters did not have matching fixture data: LoanFixture fixture
Information: [xUnit.net 00:00:22.8598342]       Stack Trace:
Information: [xUnit.net 00:00:22.8607783]         
Information: [xUnit.net 00:00:22.8615987]         ----- Inner Stack Trace #1 (System.MissingMethodException) -----
Information: [xUnit.net 00:00:22.8624251]            at Moq.Proxy.CastleProxyFactory.IsMethodVisible(MethodInfo method, String& messageIfNotVisible)
Information: [xUnit.net 00:00:22.8632101]         C:\projects\moq4\Source\Mock.cs(811,0): at Moq.Mock.ThrowIfSetupMethodNotVisibleToProxyFactory(MethodInfo method)
Information: [xUnit.net 00:00:22.8640470]         C:\projects\moq4\Source\Mock.cs(439,0): at Moq.Mock.<>c__DisplayClass62_0`1.<Setup>b__0()
Information: [xUnit.net 00:00:22.8648863]         C:\projects\moq4\Source\PexProtector.cs(61,0): at Moq.PexProtector.Invoke[T](Func`1 function)
Information: [xUnit.net 00:00:22.8656833]         C:\projects\moq4\Source\Mock.cs(432,0): at Moq.Mock.Setup[T](Mock`1 mock, Expression`1 expression, Condition condition)
Information: [xUnit.net 00:00:22.8664444]         C:\projects\moq4\Source\Mock.Generic.cs(263,0): at Moq.Mock`1.Setup(Expression`1 expression)
Information: [xUnit.net 00:00:22.8672662]         s\Sekhavat\Banking\Banking.LoanManagement.Domain.Tests\Core\LoanFixture.cs(98,0): at Banking.LoanManagement.Domain.Tests.Core.LoanFixture.Initialize()
Information: [xUnit.net 00:00:22.8680978]         s\Sekhavat\Banking\Banking.LoanManagement.Domain.Tests\Core\LoanFixture.cs(36,0): at Banking.LoanManagement.Domain.Tests.Core.LoanFixture..ctor()
Information: [xUnit.net 00:00:22.8688788]         ----- Inner Stack Trace #2 (Xunit.Sdk.TestClassException) -----
Information: [xUnit.net 00:00:22.8696267]         
Error: [xUnit.net 00:00:22.9288297] Banking.LoanManagement.Domain.Tests.Loan.LoanTests.Loan_should_be_approved_with_default_parameters [FAIL]
Information: [xUnit.net 00:00:22.9416907]       System.AggregateException : One or more errors occurred.
Information: [xUnit.net 00:00:22.9426841]       ---- System.MissingMethodException : Method not found: 'Boolean Castle.DynamicProxy.ProxyUtil.IsAccessible(System.Reflection.MethodBase, System.String ByRef)'.
Information: [xUnit.net 00:00:22.9435631]       ---- The following constructor parameters did not have matching fixture data: LoanFixture fixture
Information: [xUnit.net 00:00:22.9553793]       Stack Trace:
Information: [xUnit.net 00:00:22.9564909]         
Information: [xUnit.net 00:00:22.9574191]         ----- Inner Stack Trace #1 (System.MissingMethodException) -----
Information: [xUnit.net 00:00:22.9583584]            at Moq.Proxy.CastleProxyFactory.IsMethodVisible(MethodInfo method, String& messageIfNotVisible)
Information: [xUnit.net 00:00:22.9591998]         C:\projects\moq4\Source\Mock.cs(811,0): at Moq.Mock.ThrowIfSetupMethodNotVisibleToProxyFactory(MethodInfo method)
Information: [xUnit.net 00:00:22.9600292]         C:\projects\moq4\Source\Mock.cs(439,0): at Moq.Mock.<>c__DisplayClass62_0`1.<Setup>b__0()
Information: [xUnit.net 00:00:22.9608638]         C:\projects\moq4\Source\PexProtector.cs(61,0): at Moq.PexProtector.Invoke[T](Func`1 function)
Information: [xUnit.net 00:00:22.9617014]         C:\projects\moq4\Source\Mock.cs(432,0): at Moq.Mock.Setup[T](Mock`1 mock, Expression`1 expression, Condition condition)
Information: [xUnit.net 00:00:22.9625177]         C:\projects\moq4\Source\Mock.Generic.cs(263,0): at Moq.Mock`1.Setup(Expression`1 expression)
Information: [xUnit.net 00:00:22.9633284]         s\Sekhavat\Banking\Banking.LoanManagement.Domain.Tests\Core\LoanFixture.cs(98,0): at Banking.LoanManagement.Domain.Tests.Core.LoanFixture.Initialize()
Information: [xUnit.net 00:00:22.9642166]         s\Sekhavat\Banking\Banking.LoanManagement.Domain.Tests\Core\LoanFixture.cs(36,0): at Banking.LoanManagement.Domain.Tests.Core.LoanFixture..ctor()
Information: [xUnit.net 00:00:22.9649977]         ----- Inner Stack Trace #2 (Xunit.Sdk.TestClassException) -----
Information: [xUnit.net 00:00:22.9657738]         
Information: [xUnit.net 00:00:23.0122531]   Finished:    Banking.LoanManagement.Domain.Tests
Warning: System.AppDomainUnloadedException: Attempted to access an unloaded AppDomain. This can happen if the test(s) started a thread but did not stop it. Make sure that all the threads started by the test(s) are stopped before completion.
Information: SpecRun: not SpecRun assembly - skip: C:\BuildAgent\_work\7\s\Sekhavat\Banking\Banking.AccountManagement.Domain.Tests\bin\Debug\Banking.AccountManagement.Domain.Tests.dll
Information: SpecRun: not SpecRun assembly - skip: C:\BuildAgent\_work\7\s\Sekhavat\Banking\Banking.LoanManagement.Domain.Tests\obj\Debug\Banking.LoanManagement.Domain.Tests.dll
Information: SpecRun: not SpecRun assembly - skip: C:\BuildAgent\_work\7\s\Sekhavat\Banking\Banking.LoanManagement.Domain.Tests\bin\Debug\Banking.LoanManagement.Domain.Tests.dll
Information: SpecRun: not SpecRun assembly - skip: C:\BuildAgent\_work\7\s\Sekhavat\Banking\Banking.LoanManagement.Application.AcceptanceTests\obj\Debug\Banking.LoanManagement.Application.AcceptanceTests.dll
Information: SpecRun: not SpecRun assembly - skip: C:\BuildAgent\_work\7\s\Sekhavat\Banking\Banking.LoanManagement.Application.AcceptanceTests\bin\Debug\Banking.LoanManagement.Application.AcceptanceTests.dll
Information: SpecRun: not SpecRun assembly - skip: C:\BuildAgent\_work\7\s\Sekhavat\Banking\Banking.CustomerManagement.Domain.Tests\obj\Debug\Banking.CustomerManagement.Domain.Tests.dll
Information: SpecRun: not SpecRun assembly - skip: C:\BuildAgent\_work\7\s\Sekhavat\Banking\Banking.CustomerManagement.Domain.Tests\bin\Debug\Banking.CustomerManagement.Domain.Tests.dll
Information: SpecRun: not SpecRun assembly - skip: C:\BuildAgent\_work\7\s\Sekhavat\Banking\Banking.CompositionRoot\bin\Debug\Banking.LoanManagement.Domain.Tests.dll
Information: SpecRun: not SpecRun assembly - skip: C:\BuildAgent\_work\7\s\Sekhavat\Banking\Banking.AccountManagement.Domain.Tests\obj\Debug\Banking.AccountManagement.Domain.Tests.dll
Information: SpecRun: not SpecRun assembly - skip: C:\BuildAgent\_work\7\s\Sekhavat\Banking\Banking.LoanManagement.Application\bin\Debug\Microsoft.QualityTools.Testing.Fakes.dll
Failed   Banking.LoanManagement.Domain.Tests.Loan.LoanTests.Loan_should_be_created_with_default_parameters
Error Message:
System.AggregateException : One or more errors occurred.
---- System.MissingMethodException : Method not found: 'Boolean Castle.DynamicProxy.ProxyUtil.IsAccessible(System.Reflection.MethodBase, System.String ByRef)'.
---- The following constructor parameters did not have matching fixture data: LoanFixture fixture
Stack Trace:
----- Inner Stack Trace #1 (System.MissingMethodException) -----
at Moq.Proxy.CastleProxyFactory.IsMethodVisible(MethodInfo method, String& messageIfNotVisible)
at Moq.Mock.ThrowIfSetupMethodNotVisibleToProxyFactory(MethodInfo method) in C:\projects\moq4\Source\Mock.cs:line 811
at Moq.Mock.<>c__DisplayClass62_0`1.<Setup>b__0() in C:\projects\moq4\Source\Mock.cs:line 439
at Moq.PexProtector.Invoke[T](Func`1 function) in C:\projects\moq4\Source\PexProtector.cs:line 61
at Moq.Mock.Setup[T](Mock`1 mock, Expression`1 expression, Condition condition) in C:\projects\moq4\Source\Mock.cs:line 432
at Moq.Mock`1.Setup(Expression`1 expression) in C:\projects\moq4\Source\Mock.Generic.cs:line 263
at Banking.LoanManagement.Domain.Tests.Core.LoanFixture.Initialize() in C:\BuildAgent\_work\7\s\Sekhavat\Banking\Banking.LoanManagement.Domain.Tests\Core\LoanFixture.cs:line 98
at Banking.LoanManagement.Domain.Tests.Core.LoanFixture..ctor() in C:\BuildAgent\_work\7\s\Sekhavat\Banking\Banking.LoanManagement.Domain.Tests\Core\LoanFixture.cs:line 36
----- Inner Stack Trace #2 (Xunit.Sdk.TestClassException) -----
Error Message:
System.AggregateException : One or more errors occurred.
---- System.MissingMethodException : Method not found: 'Boolean Castle.DynamicProxy.ProxyUtil.IsAccessible(System.Reflection.MethodBase, System.String ByRef)'.
---- The following constructor parameters did not have matching fixture data: LoanFixture fixture
Stack Trace:
----- Inner Stack Trace #1 (System.MissingMethodException) -----
at Moq.Proxy.CastleProxyFactory.IsMethodVisible(MethodInfo method, String& messageIfNotVisible)
at Moq.Mock.ThrowIfSetupMethodNotVisibleToProxyFactory(MethodInfo method) in C:\projects\moq4\Source\Mock.cs:line 811
at Moq.Mock.<>c__DisplayClass62_0`1.<Setup>b__0() in C:\projects\moq4\Source\Mock.cs:line 439
at Moq.PexProtector.Invoke[T](Func`1 function) in C:\projects\moq4\Source\PexProtector.cs:line 61
at Moq.Mock.Setup[T](Mock`1 mock, Expression`1 expression, Condition condition) in C:\projects\moq4\Source\Mock.cs:line 432
at Moq.Mock`1.Setup(Expression`1 expression) in C:\projects\moq4\Source\Mock.Generic.cs:line 263
at Banking.LoanManagement.Domain.Tests.Core.LoanFixture.Initialize() in C:\BuildAgent\_work\7\s\Sekhavat\Banking\Banking.LoanManagement.Domain.Tests\Core\LoanFixture.cs:line 98
at Banking.LoanManagement.Domain.Tests.Core.LoanFixture..ctor() in C:\BuildAgent\_work\7\s\Sekhavat\Banking\Banking.LoanManagement.Domain.Tests\Core\LoanFixture.cs:line 36
----- Inner Stack Trace #2 (Xunit.Sdk.TestClassException) -----
Error Message:
System.AggregateException : One or more errors occurred.
---- System.MissingMethodException : Method not found: 'Boolean Castle.DynamicProxy.ProxyUtil.IsAccessible(System.Reflection.MethodBase, System.String ByRef)'.
---- The following constructor parameters did not have matching fixture data: LoanFixture fixture
Stack Trace:
----- Inner Stack Trace #1 (System.MissingMethodException) -----
at Moq.Proxy.CastleProxyFactory.IsMethodVisible(MethodInfo method, String& messageIfNotVisible)
at Moq.Mock.ThrowIfSetupMethodNotVisibleToProxyFactory(MethodInfo method) in C:\projects\moq4\Source\Mock.cs:line 811
at Moq.Mock.<>c__DisplayClass62_0`1.<Setup>b__0() in C:\projects\moq4\Source\Mock.cs:line 439
at Moq.PexProtector.Invoke[T](Func`1 function) in C:\projects\moq4\Source\PexProtector.cs:line 61
at Moq.Mock.Setup[T](Mock`1 mock, Expression`1 expression, Condition condition) in C:\projects\moq4\Source\Mock.cs:line 432
at Moq.Mock`1.Setup(Expression`1 expression) in C:\projects\moq4\Source\Mock.Generic.cs:line 263
at Banking.LoanManagement.Domain.Tests.Core.LoanFixture.Initialize() in C:\BuildAgent\_work\7\s\Sekhavat\Banking\Banking.LoanManagement.Domain.Tests\Core\LoanFixture.cs:line 98
at Banking.LoanManagement.Domain.Tests.Core.LoanFixture..ctor() in C:\BuildAgent\_work\7\s\Sekhavat\Banking\Banking.LoanManagement.Domain.Tests\Core\LoanFixture.cs:line 36
----- Inner Stack Trace #2 (Xunit.Sdk.TestClassException) -----
Test Run Failed.
Failed   Banking.LoanManagement.Domain.Tests.Loan.LoanTests.Loan_should_be_cancelled_with_default_parameters
Failed   Banking.LoanManagement.Domain.Tests.Loan.LoanTests.Loan_should_be_approved_with_default_parameters
Attachments:
  C:\BuildAgent\_work\7\TestResults\17f73feb-6e67-4c40-97d1-c10d235fac03\TFS$_TFS 2017-10-10 11_50_16.coverage
Total tests: 6. Passed: 3. Failed: 3. Skipped: 0.
Test execution time: 29.5806 Seconds
Results File: C:\BuildAgent\_work\7\TestResults\TFS$_TFS 2017-10-10 11_50_40.trx
VSTest Test Run failed with exit code: 1
Publishing Test Results...
Test results remaining: 6

@stakx
Copy link
Member

stakx commented Oct 10, 2017

@sbabaei, @smithkl42 : It's really difficult to do something about this issue as long as we don't have an isolated repro code that exhibits the problem.

@sbabaei: You're saying you're only having this issue on TFS. Could you please verify a few things:

  • Which versions of Moq and Castle Core are you using?
  • Which platform (including version) is your code targeting?
  • Could this possibly be a caching issue on your TFS server (i.e. packages not getting restored cleanly, wrong package versions get used, dirty build directory from previous builds, etc.)? Can you rule this out by cleaning your TFS build directories and NuGet package cache?

@sbdevman
Copy link

@stakx
Yes I use TFS 2015 , xUnit 2.3.0, Moq 4.7.137,Castle.Core 4.2.0
I have using xUnit Desktop platform using .Net 4.5.2 and Visual Studio 2017 Enterprise

@jonorossi
Copy link
Member

I've just attempted to reproduce this with the most basic components. I've got:

  • castle.core.4.1.1\Castle.Core.dll
  • castle.core.4.2.0\Castle.Core.dll
  • Moq.dll (4.7.127)
  • Program.cs (see below)
  • castle.core.4.2.0\Program.exe.config (binding redirect required to allow use of 4.2.0 with assembly version 4.0.0.0, otherwise you'll get a FileNotFoundException)

I then compile Program.cs ONCE using Castle.Core.dll 4.1.1:

csc /r:Moq.dll /r:castle.core.4.1.1/Castle.Core.dll Program.cs

Copy it to both castle.core.4.1.1 and castle.core.4.2.0 along with Moq.dll, and run it. Both output:

True
True

Program.cs:

namespace MissingMethodExceptionTest
{
    class Program
    {
        static void Main(string[] args)
        {
            // Castle
            System.Reflection.MethodInfo method = typeof(IService).GetMethod("Test");
            string messageIfNotVisible;
            bool result = Castle.DynamicProxy.ProxyUtil.IsAccessible(method, out messageIfNotVisible);
            System.Console.WriteLine(result);

            // Moq
            var mock = new Moq.Mock<IService>();
            mock.Setup(x => x.Test())
                .Returns(true);
            System.Console.WriteLine(mock.Object.Test());
        }
    }

    public interface IService
    {
        bool Test();
    }
}

It definitely appears to be an environment or NuGet issue.

@stakx
Copy link
Member

stakx commented Oct 10, 2017

It definitely appears to be an environment or NuGet issue.

@jonorossi - I agree. @sbabaei is having the issue with Moq 4.7.137 and Castle Core 4.2.0, and the former has been compiled against the latter. There's nothing wrong with the DLLs themselves as far as I can see (I checked Moq's AssemblyRef entries and ran PEVerify on both assemblies, too).

I have this one suspicion about the recent change of Castle Core's assembly version. Instead of steadily increasing, it has decreased from 4.1.1.0 to 4.0.0.0. I wouldn't be surprised if this leads to tools such as NuGet or the default MSBuild targets to do something wrong. I can't back this up in any way, though, perhaps someone more knowledgeable can judge whether that's plausible at all.

Other than that, my main advice to affected users at this point would be to clean their package cache and build output directories and see whether this helps.

@jonorossi
Copy link
Member

I'm going to close this issue now, we've worked out that the assemblies are valid and we didn't making a breaking API change, but won't know if NuGet did something silly causing the wrong assemblies to be provided.

@rytmis
Copy link

rytmis commented Apr 21, 2018

I've got a semi-interesting continuation to this: I'm trying to run xunit tests that use Moq using ReSharper's unit test runner.

Apparently ReSharper ships a copy of Castle.Core as part of the runner, so Moq ends up calling that, and produces this exception. Now, the file version for the R# copy is 4.0.0 whereas the version I've got installed is 4.2.1.

Since both copies have the same assembly version, though, I don't seem to have any way of forcing the newer assembly to be used via binding redirects.

@stakx
Copy link
Member

stakx commented Apr 21, 2018

@rytmis, perhaps you can tell that unit test runner to execute your tests in a separate AppDomain...?

@rytmis
Copy link

rytmis commented Apr 21, 2018

The option is there in R#'s settings, but it doesn't seem to have any effect on this issue:

image

image

Is this a "file a bug at JetBrains" kind of situation, then?

@stakx
Copy link
Member

stakx commented Apr 21, 2018

@rytmis - don't know, I don't use ReSharper. However, I'd expect that its test runner should better isolate your test code from its own implementation specifics. On the other hand, it can be argued that Castle Core has been versioned "incorrectly" (whether that's true or not). I find it hard to say which component is at fault in your particular scenario.

@rytmis
Copy link

rytmis commented Apr 21, 2018

I suppose it's a case of "a little bit of both" -- the problem wouldn't be here were it not for R#'s behavior, but the Castle Core versioning strategy leaves me with no workaround, either. 🤷‍♂️

I guess I'll try and file this at JetBrains and see what they come up with.

@jonorossi
Copy link
Member

I'm running an older version of ReSharper, what version are you running?

I don't think there is anything we can do about it, if the runner loads its version of Castle Core into the AppDomain first then Moq won't get to use its own version, I don't think assembly versions and binding redirects would solve this issue. I assume ReSharper has changed; even though Moq (and other mocking libraries) used to ILMerge Castle Core so it wouldn't have these problems other people would have picked up this problem before now using Castle Core directly, e.g. us.

This actually sounds like the same sort of problem that the Azure Functions .NET SDK has where it uses JSON.NET itself which means you can't choose what version gets loaded and can't use your version.

Let us know when you log the issue with JetBrains.

@rytmis
Copy link

rytmis commented Apr 22, 2018

Did that yesterday. 😊

[Edit:] Oh, and I'm running R# 2018.1, the latest published version. Curiously enough, Rider does not exhibit this problem.

@victor-yarema
Copy link

Today I have got an exception with text.
Message: System.MissingMethodException : Method not found: 'Void Castle.DynamicProxy.ProxyGenerationOptions.AddDelegateTypeMixin(System.Type)'.
I made some changes to source code of the test, it triggered the rebuild of the test project and then everything returned back to successful.
BTW, I don't use ReSharper. I did start test from Test Explorer panel in VS 2017.
The tests were OK before the issue came out and returned back to normal after test project rebuild. I have no idea what exactly happened.
Project dependencies are:

  • Microsoft.NET.Test.Sdk v15.9.0
  • Moq v4.13.0 (depends on Castle.Core v4.4.0)
  • NUnit v3.11.0
  • NUnit3TestAdapter v3.15.1

@jonorossi
Copy link
Member

Your exception appears unrelated to the reported issue here.

ProxyGenerationOptions.AddDelegateTypeMixin is new in v4.4.0, so I'd guess that you had a stale pre-4.4.0 version in one of your bin directories which got cleaned during a rebuild.

Do you have any other libraries using Castle.Core? EntityFramework Core's proxy support?

@stakx
Copy link
Member

stakx commented Oct 16, 2019

I'd guess that you had a stale pre-4.4.0 version [...] Do you have any other libraries using Castle.Core?

I agree, this is most likely a NuGet / dependency issue. This is essentially a duplicate of devlooped/moq#935, which was caused by an old version of Castle.Core lurking around. (NuGet unfortunately favors the lowest compatible version instead of the most recent one, which can cause this and similar problems.)

@victor-yarema
Copy link

Sorry for not being clear enough. I didn't mean that my problem was related to this one.
I just wanted to share the information about something similar and how it was fixed by rebuild.
Sorry again for confusion.

@jonorossi , thanks for your suggestion about older stale version. I did ran into that problem again. And I did check the version of Castle.Core.dll in output folder. And you were totally right, it has v4.2.0 ("product version" of dll). I have also checked and confirmed that the file completely matches the one in ".nuget/packages/castle.core/4.2.0/lib/netstandard1.3".

@stakx , thatnks for the link to the issue. This is exactly what I've got.

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

6 participants