This is a migrated thread and some comments may be shown as answers.

Mocking Private Methods and using MemberData Attribute xUnit

4 Answers 1206 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Shawn
Top achievements
Rank 1
Shawn asked on 27 Jul 2016, 02:00 PM

I noticed some behavior with maybe xUnit and JustMock when testing private methods.   By below setup works fine and the tests run, however in my "MemberData" class, if i pass in more that one dataset for testing, then when the second time the test runs with the new set of data, the private method code never gets executed.   It gets to the "CreateUpdateFavoriteFacility" code in my api class and then just "steps over" the call to my private method. 

 

 

Here is my Test Setup:

[Theory]
        [MemberData("FacilityFavorite",
            MemberType =typeof(FavoriteTestData))]
        [Trait("BusinessTests", "FacilityTests")]
        public void CreateUpdateFavoriteFacility_CreateUpdateFavorites(Guid employeeID, Guid favoriteFacilityID)
        {
            //arrange
            var context = Mock.Create<jhaCommon>(Constructor.Mocked);
            var api = Mock.Create<JHADirectoryServiceAPI>(context);
 
            Mock.Arrange(() => api.CreateUpdateFavoriteFacility(Arg.AnyGuid, Arg.AnyGuid)).CallOriginal().MustBeCalled();
            Mock.Arrange(() => Logger.LogError(Arg.IsAny<Exception>())).OccursNever();
            Mock.Arrange(() => context.FavoriteTypes.Department()).Returns(() => FakeDataSource.FakeFavoriteTypes().Where(ft => ft.FavoriteType1.ToLower() == "department").FirstOrDefault());
            Mock.Arrange(() => context.PhonelistFavorites).ReturnsCollection(FakeDataSource.FakePhoneListFavorites());
 
            dynamic apiWrap = Mock.NonPublic.Wrap(api);
            Mock.NonPublic.Arrange(apiWrap.CreateUpdateFavorite(ArgExpr.IsAny<Guid>(), ArgExpr.IsAny<Guid>(), ArgExpr.IsAny<FavoriteType>())).CallOriginal();
             
 
            //act
            var client = new JHADirectoryService(api);
            client.CreateUpdateFavoriteFacility(employeeID, favoriteFacilityID);
 
            //assert
            Mock.Assert(api);
        }

 

Here is my TestDataClass

public static class FavoriteTestData
    {
        #region Private Members
        private static List<object[]> _facilityFavorite = new List<object[]>
        {
            new object[] { new Guid("00000000-0000-0000-0000-000000000000") , new Guid("00000000-0000-0000-0000-000000000000") },
            new object[] { new Guid("11111111-1111-1111-1111-111111111111") , new Guid("11111111-1111-1111-1111-111111111111") }
             
        };
        #endregion
 
        #region Public Properties
        public static IEnumerable<object[]> FacilityFavorite
        {
            get { return _facilityFavorite; }
        }
        #endregion
    }

 

Here is my code in my client class.  This is the entry point of my test:

public void CreateUpdateFavoriteFacility(Guid employeeID, Guid favoriteEmployeeID)
       {
           try
           {
               _api.CreateUpdateFavoriteFacility(employeeID, favoriteEmployeeID);
           }
           catch (Exception ex)
           {
               Logger.LogError(ex);
           }
       }

Here is my "api" Code:

public void CreateUpdateFavoriteFacility(Guid employeeID, Guid favoriteFacilityID)
{
   CreateUpdateFavorite(employeeID, favoriteFacilityID, _context.FavoriteTypes.Department());
}
private void CreateUpdateFavorite(Guid employeeID, Guid favoriteObjectID, FavoriteType type)
{
  //do stuff
}

4 Answers, 1 is accepted

Sort by
0
Shawn
Top achievements
Rank 1
answered on 27 Jul 2016, 03:07 PM

I've also found that when using Inline data, this happens too...

        [InlineData("55150DE3-5493-4E57-AAEF-9A7A9E576A88", "00000000-0000-0000-0000-000000000000")]
        [InlineData("55150DE3-5493-4E57-AAEF-9A7A9E576A88", "A159BAA4-725F-4DFF-8BA2-82C2073D87C5")]
        [InlineData("11111111-1111-1111-1111-111111111111", "A159BAA4-725F-4DFF-8BA2-82C2073D87C5")]

If i run the inline data tests individually, things are fine.  But if i run them together, then it seems like something with how the NonPublic method is loaded up, it just never executes it during the same "Run"

0
Nikolay Valchev
Telerik team
answered on 29 Jul 2016, 08:15 AM
Hello Shawn,

Sorry for the inconvenience!
We tried to reproduce both cases you reported us but, unfortunately, neither of them was successful. Could you create a small sample solution with this issues reproduced in it and send it to us, so we can investigate?

Best Regards,
Nikolay Valchev
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
0
Shawn
Top achievements
Rank 1
answered on 01 Aug 2016, 03:58 PM

Here is the attached .zipfile with the solution.   This contains a working service as well as a test project that runs 2 tests.  One succeeds and one fails with demonstrates the issue.

To get the zip. just rename the TestService.gif to TestService.zip since this site won't allow you to upload anything but images.

0
Nikolay Valchev
Telerik team
answered on 04 Aug 2016, 10:35 AM
Hello Shawn,

Thank you for the follow up!
We've managed to reproduce your issue thanks to the solution you sent us!
What I could understand from both of your examples (the one you initially sent us and the one contained in the TestService solution) is that you are trying to mock the creation of you api object but you still want the original definition of its methods to be called. If this is the case, I would recommend you just to instantiate the object with Mock.Create<T>(Behavior, params object[]) overload and pass Behavior.CallOriginal as behavior, this way no further arrangement of this instance would be needed (I've tested it with both of your examples and it worked).

Best Regards,
Nikolay Valchev
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
Tags
General Discussions
Asked by
Shawn
Top achievements
Rank 1
Answers by
Shawn
Top achievements
Rank 1
Nikolay Valchev
Telerik team
Share this question
or