简体   繁体   中英

How to mock the dependency inside constructor?

I need to test the function GetPollData() and i have written Apitest class and created mock object of that class and created a test method TestGetPollData() that will check the return value and expected value are
equal or not.But i'm getting the return value as 20 instead of expected 10.I debugged and checked that the business object created inside the API
class constructor is not mocked and that dependency is returning the value initialized in the class rather than mocked value that i wanted to return.Is there a any way i can mock the object created inside the constructor or make the Apitest work as i expect.I am using nunit framework for testing. please tell me what i did wrong and what i should do?

 public class API
     {  
        public Business business { get; set; }

        public API()
        {
           business=new Business();
        }

        public int GetPollData()
        {
           return business.polltime();
        }
      }

 public class Business
   {
        public int polltime()
        {
        return Service.poll;
        }
   }    

 public class Service
    {
    public int poll=20;
    }

//API TEST CLASS
 public class Apitest
     {
        private Mock<API> api = new Mock<API>();
        API ApiObj = new ApiObj();

        // Testing the GetPollData method 
        public TestGetPollData()
          {
           api.Setup( x => x.GetPollData()).Returns(10);
           int value=ApiObj.GetPollData();
           Assert.AreEqual(10,value);
          }
       }

There are restrictions about what you can mock using Moq. This is covered here in more detail.

Can I use moq Mock<MyClass> to mock a class, not an interface?

It is more usual to use Moq with an interface or at least an abstract class.

I've refactored your code so that API implements interface IAPI. IAPI is then mocked.

I've changed your test method so that you're calling the GetPollData() method from the mocked object rather then the real object.

Its also recommended to inject your dependency on the Business class into the constructor for API so you can Mock that later if need be. I'll let you do that.

using Moq;
using NUnit.Framework;

namespace EntitlementServer.Core.Tests
{
    public interface IAPI
    {
        int GetPollData();
    }

    public class API : IAPI
    {
        public Business business { get; set; }

        public API()
        {
            business = new Business();
        }

        public int GetPollData()
        {
            return 20;
        }
    }

    public class Business
    {
        public int polltime()
        {
            return Service.poll;
        }
    }

    public static class Service
    {
        public static int poll = 20;
    }

    [TestFixture]
    public class Apitest
    {
        // Testing the GetPollData method 
        [Test]
        public void TestGetPollData()
        {
            var api = new Mock<IAPI>();
            api.Setup(x => x.GetPollData()).Returns(10);
            int value = api.Object.GetPollData();

            Assert.AreEqual(10, value);
        }
    }
}

You have to refactor it by injecting the dependency.

public class API { 
    public Business business { get; set; }

    public API( Business b )
    {
       business= b;
    }

    public int GetPollData()
    {
       return business.polltime();
    }
 }

In test, pass your mocked Business into API, and test if polltime of the mocked instance getting called.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM