Updating JustMock 2013-2014

11 posts, 1 answers
  1. Sven
    Sven avatar
    14 posts
    Member since:
    Aug 2012

    Posted 10 Sep 2014 Link to this post

    Hello.  I am having some difficulty getting an update to JustMock working for our existing unit test library. 

    Details:
    We were on 2013.2.611 and have upgraded to 2014.2.811.1. 
    We use TFS Build to run unit tests (under MSTest).  I have already set up the code activity (including environmental settings) from the last version based on the JustMock guide and it was working with 100% success rate on the old version. 
    I updated the library to latest one from the new JustMock installation. 

    Builds completes and most of the JustMock related unit tests are failing with many similar error messages such as:
    Telerik.JustMock.MockException: Arranging the return value of a constructor call is not supported.
    Telerik.JustMock.MockException: Can not instantiate proxy of class: Could not find a parameterless constructor.

    Are there any major changes between the versions that could be causing this?  Something I forgot to update?

  2. Stefan
    Admin
    Stefan avatar
    198 posts

    Posted 11 Sep 2014 Link to this post

    Hi Sven,

    Since last year we've made numerous improvements to the library that strive to make writing unit tests more robust and less error prone. Unfortunately, this tightening often results in broken tests. Such tests were actually broken all this time without you knowing it.

    The first exception: Arranging the return value of a constructor call is not supported.
    It results from code like this:
    Mock.Arrange(() => new Fabrikam()).Returns(Mock.Create<Fabrikam>());
    Although such code compiles, JustMock has actually never supported arranging the return value of new expressions. You can only override the body of the specified constructor. To prevent errors in tests there's now an explicit check for this mistake. The fix is to simply remove the .Returns() clause from all such arrangements. If the test worked before, it will continue to work when you remove the .Returns() clause, because it has always been tantamount to a no-op.

    The other exception: Can not instantiate proxy of class: Could not find a parameterless constructor.
    I'm not sure what change in JustMock causes this. Can you show me a short snippet of the test code together with the related class constructors?

    I will do everything in my power to make the upgrade as painless as possible for you. I hope this helps.

    Regards,
    Stefan
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  3. DevCraft R3 2016 release webinar banner
  4. Sven
    Sven avatar
    14 posts
    Member since:
    Aug 2012

    Posted 11 Sep 2014 in reply to Stefan Link to this post

    Hi Stefan.  Thanks for taking the time to reply.I will look into the first error and see if I can correct it based on your information.  As for the other error, it occurs here:

    var mockgateway = Mock.Create<Gateway>(Behavior.Loose, Constructor.Mocked);

    Telerik.JustMock.MockException: Can not instantiate proxy of class: DataAccess.Gateway.
    Could not find a constructor that would match given arguments:
    Telerik.JustMock.Constructor
    Result StackTrace:
    at Telerik.JustMock.Core.MocksRepository.Create(Type type, MockCreationSettings settings)
       at Telerik.JustMock.MockBuilder.Create(MocksRepository repository, Type type, Object[] constructorArgs, Nullable`1 behavior, Type[] additionalMockedInterfaces, Nullable`1 mockConstructorCall, IEnumerable`1 additionalProxyTypeAttributes, List`1 supplementaryBehaviors, List`1 fallbackBehaviors, List`1 mixins, Expression`1 interceptorFilter)
       at Telerik.JustMock.Mock.<>c__DisplayClass89`1.<Create>b__88()
       at Telerik.JustMock.Core.ProfilerInterceptor.GuardInternal[T](Func`1 guardedAction)
       at Telerik.JustMock.Mock.Create[T](Behavior behavior, Object[] args)
       at ServiceLibrary.UnitTests...

    Copy of constructor:
    public class Gateway
    {       
     public Gateway()
      //: this(false)
     {
     } ... // Overloaded constructors follow
    }
  5. Stefan
    Admin
    Stefan avatar
    198 posts

    Posted 12 Sep 2014 Link to this post

    Hi Sven,

    The correct form of that Create method overload is:

    var mockgateway = Mock.Create<Gateway>(Constructor.Mocked, Behavior.Loose);
    In your code the two parameters are in the wrong order, which hits the Create(params object[] args) overload and JustMock tries to find a constructor with the given arguments.

    I am currently unable to track if and when the overload you're using existed. In any case, the fix is to just reorder the parameters in such calls to Mock.Create.

    I would also urge you to check whether the default RecursiveLoose behavior is actually more suitable to your needs. In most cases it leads to shorter and more maintainable tests. Also, since it is the default, you can just create mocks with the shortest Create overload: Mock.Create<Gateway>().

    Regards,
    Stefan
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  6. Sven
    Sven avatar
    14 posts
    Member since:
    Aug 2012

    Posted 12 Sep 2014 in reply to Stefan Link to this post

    Thanks much Stefan, you have been very helpful.  Strange that the previous version of JustMock we were using was working with the reversed parameters.
  7. Stefan
    Admin
    Stefan avatar
    198 posts

    Posted 15 Sep 2014 Link to this post

    Hello Sven,

    I'm happy that you've resolved the issues coming from the JustMock version upgrade. If you run into any other head-scratchers don't hesitate to contact us again.

    Regards,
    Stefan
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  8. Sven
    Sven avatar
    14 posts
    Member since:
    Aug 2012

    Posted 15 Sep 2014 in reply to Stefan Link to this post

    Hey Stephan.

    How bout this error:

    System.MissingMethodException: Method 'AnyReason' not found on type AnalystMedicare.AnalystMedicare

    The AnyReason method exists in the base class.  Has there been a change around that.  Here is the offending line:

    Mock.NonPublic.Arrange<bool>(target, "AnyReason", ArgExpr.Ref(billLines[1])).IgnoreArguments().IgnoreInstance().Returns(true);


  9. Stefan
    Admin
    Stefan avatar
    198 posts

    Posted 16 Sep 2014 Link to this post

    Hello Sven,

    Yes, there have been a few bugfixes in the NonPublic API. The non-public API was rather lax with the argument list and didn't always correctly select the wanted overload when there were multiple methods with the same name but different arguments (in particular when 'ref' arguments were involved).

    I surmise that the signature given to Arrange() doesn't match the AnyReason method's signature. Post the AnyReason method's signature here, so that I can check whether the arrangement and the signature match. In the next release of JustMock, errors in non-public arrangements (i.e. the MissingMethodException) will be accompanied by copy-and-paste snippets in the exception message of the correct arrangement statement for every member with the given name. This will make writing non-public arrangements a breeze!

    Regards,
    Stefan
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  10. Sven
    Sven avatar
    14 posts
    Member since:
    Aug 2012

    Posted 16 Sep 2014 in reply to Stefan Link to this post

    Protected Function AnyReason(ByVal BR As CBillRowExt) As Boolean
  11. Answer
    Stefan
    Admin
    Stefan avatar
    198 posts

    Posted 17 Sep 2014 Link to this post

    Hello Sven,

    The method's argument is declared ByVal, so you shouldn't use ArgExpr.Ref there. Since you also have IgnoreArguments(), then it doesn't make sense to specify a concrete instance for the argument matcher. The correct form would then be:
    Mock.NonPublic.Arrange<bool>(target, "AnyReason", ArgExpr.IsAny<CBillRowExt>()).IgnoreInstance().Returns(true);

    Alternatively, if you actually want to match the concrete instance, the correct form would be:
    Mock.NonPublic.Arrange<bool>(target, "AnyReason", billLines[1]).IgnoreInstance().Returns(true);

    Essentially, the problem was caused by a misplaced ArgExpr.Ref.

    Regards,
    Stefan
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  12. Sven
    Sven avatar
    14 posts
    Member since:
    Aug 2012

    Posted 17 Sep 2014 in reply to Stefan Link to this post

    Excellent!  Thank much.
Back to Top
DevCraft R3 2016 release webinar banner