Mocking Private Methods

3 posts, 0 answers
  1. Shawn
    Shawn avatar
    11 posts
    Member since:
    Sep 2013

    Posted 12 Jul Link to this post

    I have a scenario that I cannot seem to get working just like i would like.

     

    I have been able to successfully write a test method against my private method just fine.

    Now, I'm trying to write a test against my public method.  In the public method, i want to the call to the private method to be mocked and return a mocked value so the remainder code in my public method will handle that result.

    However, when it comes time to execute the line of code in the public method that would call the private method, all that comes back is NULL.  I don't get my mocked value.

    Here is my current test

    var mockedClass = Mock.Create<JHADirectoryServiceAPI>(Constructor.Mocked);
     
    var autoFix = new Fixture();
    var otherPhoneDtoCollection_AM = autoFix.Create<IEnumerable<OtherPhoneDto>>();
      
    var inst = new PrivateAccessor(mockedClass);
     
    Mock.NonPublic.Arrange<IEnumerable<OtherPhoneDto>>(mockedClass, "GetOtherPhonesByOfficeID", Arg.AnyGuid)
                    .DoInstead(()=> inst.CallMethod("GetOtherPhonesByOfficeID", Arg.AnyGuid)).ReturnsCollection(otherPhoneDtoCollection_AM);

    Assume the below  code...

    Public IEnumerable<Object> GetDetails(Guid value)
    {
     
       //do some local stuff
        
       var result = GetOtherPhonesByOfficeID(value);
     
       //eval result
     
      return  myList
    }
     
    private  IEnumerable<OtherPhoneDto> GetOtherPhonesByOfficeID(Guid value)
    {
      //Do some Stuff
     
      return myList;
    }

  2. Shawn
    Shawn avatar
    11 posts
    Member since:
    Sep 2013

    Posted 12 Jul in reply to Shawn Link to this post

    Figured it out.  Had to use the Mock.NonPublic.Wrap function as mentioned here.

    http://www.telerik.com/help/justmock/advanced-usage-mocking-non-public-members-and-types.html

    ultimately, this code snippet worked.

    dynamic mockedClassWrap = Mock.NonPublic.Wrap(mockedClass);
    Mock.NonPublic.Arrange<IEnumerable<OtherPhoneDto>>(mockedClassWrap .GetOtherPhonesByOfficeID(ArgExpr.IsAny<Guid>())).Returns(otherPhoneDtoCollection_AM);

     

  3. DevCraft R3 2016 release webinar banner
  4. Svetlozar
    Admin
    Svetlozar avatar
    269 posts

    Posted 15 Jul Link to this post

    Hi,

    I am glad you've managed to resolve the issue. However I think there is something that you've missed - Mock Behaviors

    When you create a mock with Mock.Create and don't specify the behavior, its member implementation are empty stubs (because of the default behavior). Although you've arranged the private method, the public method has an empty implementation that doesn't call the original method (that calls the private method). To achieve what you want you have to create the mock with CallOriginal behavior. I prepared a small example. Consider that code

    public class Student
    {
        public string GetName()
        {
            return GetPrivateName();
        }
     
        private string GetPrivateName()
        {
            return "Svetlozar";
        }
    }

    Here is how to arrange the private method and leave the public one with the original implementation.

    [TestMethod]
    public void TestMethod1()
    {
        var mocked = Mock.Create<Student>(Behavior.CallOriginal);
        Mock.NonPublic.Arrange<string>(mocked, "GetPrivateName").Returns("Svetlio");
        Assert.AreEqual("Svetlio", mocked.GetName());          
    }

    I hope that makes sense. Let us know if you have other 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