Skip parameter evaluation?

6 posts, 1 answers
  1. Florian
    Florian avatar
    9 posts
    Member since:
    Jul 2015

    Posted 04 Aug 2015 Link to this post

    Let's say I have a class

     

    class MyClass
    {
        public virtual void MyFunc1( DateTime somedate)
        {}

        public virtual void MyFunc2( )
        {
           MyFunc1(SomeObject.SentDate)

        }

    }

    where SomeObject has a field called SentDate.

    SomeObject is in a global scope and, for some reasons, I can't provide a value for it so will always be null when mocking.

    I can arrange for MyFunc1() to do whatever I want but, when I call MyFunc2(), it will try to evaluate its parameter SomeOject.SentDate and, because SomeObject is null, this will fail with an exception.

    Is there a way to skip the evaluation of SomeObject.SentDate parameter?

  2. Kaloyan
    Admin
    Kaloyan avatar
    872 posts

    Posted 07 Aug 2015 Link to this post

    Hi Florian,

    I am not sure what exactly do you mean by "I can't provide a value for it so will always be null when mocking". This said, could you please share the failing unit test related to the above code snippet, so we can investigate for possible issues further? Thanks for this in advance.

    Regards,
    Kaloyan
    Telerik
    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. Florian
    Florian avatar
    9 posts
    Member since:
    Jul 2015

    Posted 07 Aug 2015 in reply to Kaloyan Link to this post

     

    Hi, here is the complete testing code.

    01.<P>
    02.using System;
    03.using Microsoft.VisualStudio.TestTools.UnitTesting;
    04.using Telerik.JustMock;
    05.using Telerik.JustMock.Core;  
    06. 
    07.namespace TestMock1
    08.{  
    09.[TestClass]
    10.public class UnitTest1
    11.{
    12.[TestMethod]
    13.public void TestMethod1()    
    14.{
    15.  var mock = Mock.Create<MyClass>(Behavior.CallOriginal);
    16.  Mock.Arrange(() => mock.MyFunc1(DateTime.Now)).DoNothing();
    17.  mock.MyFunc2();      
    18.}  
    19.
    20. 
    21.class SomeClass
    22.{
    23.  public DateTime SentDate { getset; } 
    24.
    25. 
    26.public class MyClass
    27.{
    28.SomeClass SomeObject;
    29. 
    30.SomeClass GetObjectFromDB()       
    31.{
    32.  SomeClass obj = new SomeClass();
    33.  // get it from DB
    34.  return obj;     
    35.}
    36. 
    37.public virtual void MyFunc1(DateTime somedate)     
    38.{
    39.  SomeObject = GetObjectFromDB();    
    40.
    41.public virtual void MyFunc2()    
    42.{
    43.   MyFunc1(SomeObject.SentDate);      
    44.}  
    45. 
    46.
    47.}</P>

     

    At line 43 the code produces an exception because SomeObject is null

    On a separate note, if I declare MyFunc2() as "internal" instead of "public", I can skip Behavior.CallOriginal and the original code is still called. I am not sure if this is a bug or feature.

     

     

     

  5. Answer
    Stefan
    Admin
    Stefan avatar
    198 posts

    Posted 11 Aug 2015 Link to this post

    Hello Florian,

    In your first question, the code of MyClass seems to be semantically incorrect, because it uses SomeObject before it being assigned. Regardless, there's no way to skip the evaluation of SomeObject.SentDate, if SomeObject is a field. If you just want to test the MyFunc2 method, you can supply a mock for SomeObject, like so:
    var mock = Mock.Create<MyClass>(Behavior.CallOriginal);
    Mock.Arrange(() => mock.MyFunc1(Arg.IsAny<DateTime>())).DoNothing();
    new PrivateAccessor(mock).SetField("SomeObject", Mock.Create<SomeClass>());
    mock.MyFunc2();

    Also, it is not a bug that making MyFunc2 internal prevents it from being mocked. When using JustMock Lite, you can only mock members that are normally accessible for inheritance. To mock internal virtual members, you need to use the InternalsVisibleTo attribute as explained in the documentation.

    Regards,
    Stefan
    Telerik
    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
  6. Florian
    Florian avatar
    9 posts
    Member since:
    Jul 2015

    Posted 11 Aug 2015 in reply to Stefan Link to this post

    Thanks for the answer. The first question was what I was looking for and you answered it.

    Regarding the second question (actually just a note) I think I was misunderstood. I didn't say internal prevents mocking, by the contrary (sort of). When the function is "virtual public" in order to call the original you have to Create the mock with Behavior.CallOriginal param or to arrange and CallOriginal.

    When the same function is declared as "virtual internal" the original is called without any of the above settings.

  7. Stefan
    Admin
    Stefan avatar
    198 posts

    Posted 12 Aug 2015 Link to this post

    Hello Florian,

    I'm glad that you got what you came for.

    Behavior.CallOriginal was not necessary when the method was internal, because JustMock was not able to override it anyway. When it's public, JustMock is able to override it and mock it out, hence the need for Behavior.CallOriginal.

    Regards,
    Stefan
    Telerik
    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