Mocking only two methods in class for unit testing Moq and XUnit

tech asuran 16 Reputation points
2021-10-16T01:48:15.803+00:00

WE have service which calls method GetUserAccountNo() in turn call other two (GetUser, CreateUser) in that service . we are using Moq and XUnit for testing Can anybody let me knw how can I mock only the GetUser and CreateUser and write unit test for the GetUserAccountNo.

I can see some people saying about making the methods as virtual. Here in this case all the methods are in same class and from same interface and public as well

Please find the code snippet

public int GetUserAccountNo (string id)
{

    if (GetUser(id)!=null )
    {
        return GetUser(id).AccountNo;
    }
    else
    {
        return CreateUser(id).AccountNo;
    }

}


public User GetUser(string id)
{

    //Get from  userAPi
    return new User();
}

public User CreateUser(string id)
{

    //Create from userAPi using  http request

    return new User();
}

Thanks

Developer technologies ASP.NET ASP.NET Core
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Bruce (SqlWork.com) 77,686 Reputation points Volunteer Moderator
    2021-10-17T16:35:05.567+00:00

    To write unit tests, the code should be designed as testable. The code should be designed to require the least mocking,

    To mock methods, they need to be virtual, or part of injected interface (better approach).

    In your case, the user api should be injectable at least, so you can mock the api calls.

    0 comments No comments

  2. Anonymous
    2021-10-18T07:57:30.77+00:00

    As far as I know, the unit test should be designed as each method will have its own test. Each method will be regarded as a unit. That means each method will have its own mock data.

    If you want to test the GetUserAccountNo, and it will use CreateUser and GetUser method. Normally, in asp.net core these two method will be inside a service class and then we will inject that service class and call it.

    If this is your codes, it will be normally mock as below:

            [Fact]
            public async Task UserAccountNo_YourClassName_WithUserNotFound()
            {
                // Arrange
                var mockRepo = new Mock<IRepository>();
                mockRepo.Setup(repo => repo.GetUserNotFound())
                    .ReturnsAsync(GetUser());
                var mockRepo = new Mock<IRepository>();
                mockRepo.Setup(repo => repo.CreateUser())
                    .ReturnsAsync(CreateUser());
                var YourClassName= new YourClassName(mockRepo.Object);
    
                // Act
                var result = await YourClassName.UserAccountNo();
    
                // Assert
                 .....
            }
    
         public User GetUserNotFound(string id)
        {
         //Build a mock data and return it 
         return new User();
         }
          public User CreateUser(string id)
        {
         //Build a mock data and return it 
         return new User();
         }
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.