2010-10-18 72 views
4

我有一个类,它执行一些内容检索,并且它有一个方法需要一些输入(过滤器)才能检索它。其中一个“输入”调用另一个方法,基本上返回一个int,我如何使用MOQ来嘲笑它?这里有一个例子:如何嘲笑返回一个int与MOQ的方法

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(); 
     } 
    } 
} 

这是“GetClientID()”方法:

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(sClientID, out nClientID)) 
      { 
       throw new Exception("No clientid found in user session, client not authenticated, please login from main page"); 
      } 

      return nClientID; 
     } 

我只是在寻找一种方式,让我在一个硬编码值传递的客户端ID,并使用它对GetDataClass类进行一些单元测试。

谢谢。

+1

没有回答你的问题,因为克劳斯比斯科夫已经做了很好的工作。但我想说,而不是一个“Util”类,我喜欢使用一个AppContext类(它实现IAppContext,这与klausbyskov的答案中的IUtil相同)。这存储了有关应用程序当前上下文的信息,例如当前用户,当前客户端或您在整个应用程序中可能需要知道的其他活动配置。这当然是个人偏好,但我认为AppContext类的意图比另一个名为“Utils”的类更清晰。 – NerdFury 2010-10-18 19:56:24

+0

感谢您的建议,不幸的是,这些课程来自不同的团队,也是我无法改变的“核心”库的一部分!我只是从它继承而来。 – Saxman 2010-10-18 21:40:30

回答

5

你不能嘲笑一种静态方法。你应该使用一些依赖注入的手段。假设你将界面你GetClientId方法部分称为IUtils像这样:

public interface IUtils 
{ 
    int GetClientId(); 
} 

,你有你的具体类如上实施Utils,但没有方法是静态的(和实施过程中的界面)。 现在注入你的接口的实现到GetDataClass 类通过改变它的构造,就像这样:

public class GetDataClass 
{ 
    private readonly IUtils utils; 

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

    //SNIP 
} 

InitRequest方法更改呼叫Utils.GetClientID()this.utils.GetClientId()

您现在可以使用模拟来实例GetDataClass类,如下所示:

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

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

就是这样。

+0

嗨klausbyskov,不幸的是,“Utils”类(以及其他类的负载已经由不同的团队实现!),没有一个是实现接口,所以我不能对其进行任何更改。也许,我应该改写我的问题:基于我原来的问题中的信息,我该如何测试**“GetDataClass”**(它需要调用“** InitRequest”**进行一些初始化),具体来说,调用**“GetConfigMetaData()”**?谢谢。 – Saxman 2010-10-18 21:38:26

+0

是什么阻止你重构*其他团队*的代码?毕竟,你们都在同一条船上。如果你解释你的代码可测试的意图,我相信他们将*必须*尽力满足你的愿望,如果他们不想看起来像专业的傻瓜。从长远来看,它将会帮助你在开发过程中使用行业最佳实践,而且绝对包括编写可测试的代码。因此,不是寻找一个解决方案(不存在)来解决设计问题,而只是重构代码。这不应该是一个很大的交易。 – 2010-10-18 21:58:44

+0

这个类(在许多其他类中)是由一个由大约15个不同项目使用的不同团队编写的“Core”库的一部分。我在这里很新,所以我的声音就像流水线一样流畅:)但是很公平,我会按这个库来重构可测试代码。谢谢! – Saxman 2010-10-19 14:48:58