开发者

How to mock a method that returns an int with MOQ

开发者 https://www.devze.com 2023-01-20 20:41 出处:网络
I have a class that does some retrieving of contents, and it has a method that requires some inputs (filters) before retrieving it. One of the \"input\" calls another method, which basically returning

I have a class that does some retrieving of contents, and it has a method that requires some inputs (filters) before retrieving it. One of the "input" calls another method, which basically returning an int, how do I mock it using MOQ? Here's an example:

namespace MyNamespace
{
    public class ConfigMetaDataColumns : MyModel
    {
        public int FieldID { get { return ValueInt("FieldID"); } }
        public int OrderId { get { return ValueInt("OrderId"); } }
        public string Label { get { return ValueString("Label"); } }
        public string FieldName { get { return ValueString("FieldName"); } }
        public int IsReadOnly { get { return ValueInt("IsReadOnly"); } }
    }

    public class GetDataClass
    {
        protected OpenSQLAccessLayer m_WITObject;

        // Input Properties
        public string GroupID;
        public string PageName;

        // Output Properties

        /// <summary>
        /// Get Config meta data
        /// </summary>
        /// <returns></returns>
        public IEnumerable<ConfigMetaDataColumns> GetConfigMetaData()
        {
            var requester = new ListRequester<OpenSQL, ConfigMetaDataColumns>(m_WITObject, "Result[0].RowCount", "Result[0].Row[{0}].");

            return requester.Items;
        }

        public void InitRequest()
        {
            User user = (User)HttpContext.Current.User;
            m_WITObject = user.NewService<OpenSQLAccessLayer>();

            m_WITObject.SetInput("MultipleResultSets", 1);
            m_WITObject.SetInput("ClientID", Utils.GetClientID());
            m_WITObject.SetInput("GroupID", GroupID);
            m_WITObject.SetInput("PageName", PageName);
            m_WITObject.Retrieve();
        }
    }
}

This is the "GetClientID()" method:

public static int GetClientID()
        {
            User oUser = (User)HttpContext.Current.User;
            int nClientID;
            string sClientID = string.Empty;

            if (String.IsNullOrEmpty(oUser.Session("clientid")))
            {
                Client oClient = new Client();
            }

            oUser = (User)HttpContext.Current.User;
            sClientID = oUser.Session("clientid");




            //If we couldn't retrieve it, throw exception
            if ( string.IsNullOrEmpty(sClientID) || !int.TryParse(sClie开发者_高级运维ntID, out nClientID))
            {
                throw new Exception("No clientid found in user session, client not authenticated, please login from main page");
            }

            return nClientID;
        }

I'm just looking for a way for me to pass in a hard-coded value for the ClientID, and use this to do some unit testing with the GetDataClass class.

Thanks.


You cannot mock a static method. You should use some means of dependency injection. Say you make your GetClientId method part of an interface called IUtils like so:

public interface IUtils
{
    int GetClientId();
} 

And you have your concrete class Utils implemented as above, but without the method being static (and implementing the interface of course). You now inject an implementation of your interface into the GetDataClass class by changing its constructor, like so:

public class GetDataClass
{
     private readonly IUtils utils;

     public GetDataClass(IUtils utils)
     {
         this.utils = utils;
     }

     //SNIP
}

In the InitRequest method you change the call Utils.GetClientID() to this.utils.GetClientId().

You are now ready to instantiate your GetDataClass class with a mock, like so:

var utilsMock = new Mock<IUtils>();
utilsMock.Setup(u => u.GetClientId()).Returns(42);

var getDataClass = new GetDataClass(utilsMock.Object);
getDataClass.InitRequest();

And that's it.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号