JustMock with NUnit and OpenCover - ElevatedMockingException

7 posts, 0 answers
  1. Josh
    Josh avatar
    4 posts
    Member since:
    Jun 2016

    Posted 01 Jul Link to this post

    I'm unable to get JustMock working with NUnit and OpenCover. JustMock works just fine without OpenCover in the mix, and OpenCover works fine without a JustMock test involved.

    I'm explicitly setting all the environment variables

    JUSTMOCK_INSTANCE=1
    COR_ENABLE_PROFILING=1
    COR_PROFILER={B7ABE522-A68F-44F2-925B-81E7488E9EC0}

    And invoking OpenCover as a Batch Command

    c:\tools\OpenCover\OpenCover.Console.exe -target:"C:\tools\NUnit\nunit-console\nunit3-console.exe" -targetargs:"%WORKSPACE%\Dev\Source\<snipped>.dll --result:Results.xml;format=nunit2" -filter:"+[*]* -[*.Tests]*" -register:user -output:Coverage.xml -hideskipped:All -skipautoprops

     

    Both OpenCover and JustMock are installed. The OpenCover dlls are registered and linked to JustMock (see attached screenshot). There is one unit test that uses JustMock to mock System.DateTimeOffset

    I get the following when I try to run the setup.

    Executing: C:\tools\NUnit\nunit-console\nunit3-console.exe
    NUnit Console Runner 3.2.1
    Copyright (C) 2016 Charlie Poole
     
    Runtime Environment
       OS Version: Microsoft Windows NT 6.1.7601 Service Pack 1
      CLR Version: 4.0.30319.42000
     
    Test Files
        c:\workspace\Tests\bin\Debug\Tests.dll
     
     
    Errors and Failures
     
    1) Error : Tests.InitializesWithCurrentTime
    Telerik.JustMock.Core.ElevatedMockingException : Cannot mock 'System.DateTimeOffset'. The profiler must be enabled to mock, arrange or execute the specified target.
    Detected active third-party profilers:
    *  (from process environment)
    Disable the profilers or link them from the JustMock configuration utility. Rest
    art the test runner and, if necessary, Visual Studio after linking.
       at Telerik.JustMock.Core.ProfilerInterceptor.ThrowElevatedMockingException(Me
    mberInfo member)
       at Telerik.JustMock.Core.MocksRepository.InterceptStatics(Type type, IEnumera
    ble`1 mixins, IEnumerable`1 supplementaryBehaviors, IEnumerable`1 fallbackBehavi
    ors, Boolean mockStaticConstructor)
       at Telerik.JustMock.MockBuilder.InterceptStatics(MocksRepository repository,
    Type type, Nullable`1 behavior, Boolean mockStaticConstructor)
       at Telerik.JustMock.Core.MocksRepository.ConvertExpressionToCallPattern(Expre
    ssion expr, CallPattern callPattern)
       at Telerik.JustMock.Core.MocksRepository.Arrange[TMethodMock](Expression expr
    , Func`1 methodMockFactory)
       at Telerik.JustMock.Mock.<>c__DisplayClass8`1.<Arrange>b__6()
       at Telerik.JustMock.Core.ProfilerInterceptor.GuardInternal[T](Func`1 guardedA
    ction)
       at Telerik.JustMock.Mock.Arrange[TResult](Expression`1 expression)

    Versions

    • NUnit 3.2.1
    • OpenCover 4.6.519.0
    • JustMock 2016.2.426.1
  2. Svetlozar
    Admin
    Svetlozar avatar
    269 posts

    Posted 06 Jul Link to this post

    Hi,

    Thank you for reaching out, that is a great question actually!

    When you link profilers you must set COR_PROFILER to be the other profiler guid, not JustMock. The CLR can attach only one profiler effectively set by COR_PROFILER. We have implemented the linking by replacing the other profiler dll path with JustMock dll path. When the CLR requests OpenCover it will load JustMock because the dll path in the registry points to JustMock. JustMock calls back the "original" profiler when done. In your case you need to have the OpenCover guid as COR_PROFILER.

    Our OpenCover integration documentation shows that you need to set only JUSTMOCK_INSTANCE, assuming that OpenCover have set COR_PROFILER and COR_ENABLE_PROFILING. We need to improve that. 

    I hope that makes sense. Let me know if you have any questions.

    Regards,
    Svetlozar
    Telerik by Progress
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. DevCraft R3 2016 release webinar banner
  4. Josh
    Josh avatar
    4 posts
    Member since:
    Jun 2016

    Posted 10 Jul in reply to Svetlozar Link to this post

    I also tried the OpenCover/JustMock integration as specified in the documentation and saw the same error.  Does that mean that the Integration isn't working as documented? Should I try specifying the environment variables explicitly, but using the OpenCover GUID this time?
  5. Josh
    Josh avatar
    4 posts
    Member since:
    Jun 2016

    Posted 11 Jul Link to this post

    I tried both ways. First, I specified the OpenCover CLSID Guid explicitly and received the same error. Then, I removed the COR_* environment variables and left only JustMock_Instance=1 set and received the same error.

    Telerik.JustMock.Core.ElevatedMockingException : Cannot mock 'System.DateTimeOffset'. The profiler must be enabled to mock, arrange or execute the specified target.
    Detected active third-party profilers:
    *  (from process environment)
    Disable the profilers or link them from the JustMock configuration utility. Restart the test runner and, if necessary, Visual Studio after linking.
       at Telerik.JustMock.Core.ProfilerInterceptor.ThrowElevatedMockingException(MemberInfo member)
       at Telerik.JustMock.Core.MocksRepository.InterceptStatics(Type type, IEnumerable`1 mixins, IEnumerable`1 supplementaryBehaviors, IEnumerable`1 fallbackBehaviors, Boolean mockStaticConstructor)
       at Telerik.JustMock.MockBuilder.InterceptStatics(MocksRepository repository,Type type, Nullable`1 behavior, Boolean mockStaticConstructor)
       at Telerik.JustMock.Core.MocksRepository.ConvertExpressionToCallPattern(Expression expr, CallPattern callPattern)
       at Telerik.JustMock.Core.MocksRepository.Arrange[TMethodMock](Expression expr, Func`1 methodMockFactory)
       at Telerik.JustMock.Mock.<>c__DisplayClass8`1.<Arrange>b__6()
       at Telerik.JustMock.Core.ProfilerInterceptor.GuardInternal[T](Func`1 guardedAction)
       at Telerik.JustMock.Mock.Arrange[TResult](Expression`1 expression)
       at Tests.InitializesWithCurrentTime()

     

    OpenCover shows as linked

  6. Svetlozar
    Admin
    Svetlozar avatar
    269 posts

    Posted 13 Jul Link to this post

    Hi,

    I just tested with OpenCover 4.6.519 and it works on my side if I don't pass the register flag to OpenCover, although I have no idea why currently.

    Here is what I did

    1. Install OpenCover
    2. regsvr32 "%localappdata%\Apps\OpenCover\x86\OpenCover.Profiler.dll" 
    3. Link OpenCover from JustMock configuration at "C:\Program Files (x86)\Telerik\JustMock\Libraries\Telerik.JustMock.Configuration.exe"
    4. SET JUSTMOCK_INSTANCE=1
    5. Run OpenCover withouth the register flag.

    It looks like passing the register flag resets our linking information. We will need more time to investigate that. Could you please check if that works for you?

    Regards,
    Svetlozar
    Telerik by Progress
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  7. Josh
    Josh avatar
    4 posts
    Member since:
    Jun 2016

    Posted 13 Jul in reply to Svetlozar Link to this post

    Thank you, that worked! I removed the -register:user flag and it worked. I'm keen to understand more about what is going on here. We were originally using the OpenCover NuGet package and switched to the install per the JustMock integration guide. The -register:user flag was vestigial from that original setup. I imagine the path laid out in the Integration guide doesn't work if OpenCover is consumed as a NuGet package, rather than as an install on the build machine?

     

     

  8. Svetlozar
    Admin
    Svetlozar avatar
    269 posts

    Posted 14 Jul Link to this post

    Hi,

    That is a great question actually. I just reviewed the OpenCover -register implementation and it turned out to be what I expected. When you pass the register flag, OpenCover does regvr32 for the OpenCover dll. You can view it here - ProfilerRegistration.cs and more specifically - Register and ExecuteRegsvr32

    What regsvr32 actually does is to store in registry the profiler dll path with the associated profiler guid so that the CLR can find and load it. Here is where JustMock comes into play, when you 'link' profilers we actually temporarily modify the registry entry and the OpenCover guid points to a JustMock profiler that does JustMock related work and callbacks the OpenCover profiler, the so called linking. When you pass the register flag, regsvr32 is called which overwrites our replaced registry entry and JustMock is not called.

    The registry edit is our workaround of the CLR limitation that there could be only one profiler per process.

    I hope that makes sense. Let me know if you have any questions.

    Regards,
    Svetlozar
    Telerik by Progress
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top
DevCraft R3 2016 release webinar banner