2012-09-24 45 views
1

下面我有一些代码,我不能单元测试,因为它试图从IIS7阅读设置,不幸的是我们每晚构建机没有IIS7。我能想到的唯一的事情就是到ServerManager的传递给方法,但随后又在来电,我将有一个ServerManager的,这将使该方法无法进行单元测试。我们使用MOQ作为我们的模拟库。如何让这个单元测试

 public ISection GetCurrentSettings(string location, Action<string> status) 
    { 
     #region Sanity Checks 

     if (string.IsNullOrEmpty(location)) 
     { 
      throw new ArgumentNullException("location"); 
     } 
     if (status == null) 
     { 
      throw new ArgumentNullException("status"); 
     } 
     #endregion 

     ISection section = null; 

     _logger.Debug(string.Format("Retrieving current IIS settings for app at {0}.", location)); 
     status("Getting current IIS settings."); 
     using (ServerManager manager = new ServerManager()) 
     { 
      var data = (from site in manager.Sites 
         from app in site.Applications 
         from vdir in app.VirtualDirectories 
         where vdir.PhysicalPath.Equals(location, StringComparison.CurrentCultureIgnoreCase) 
         select new {Website = site, App = app}).SingleOrDefault(); 

      if (data == null) 
      { 
       _logger.Debug(string.Format("Could not find an application at {0} in IIS. Going to load the defaults instead.", location)); 
       //ToDo possibly load defaults 
      } 
      else 
      { 
       _logger.Debug(string.Format("Application found in IIS with website: {0} and a path of {1}", data.Website.Name, data.App.Path)); 
       int port = 
        data.Website.Bindings.Where(b => b.EndPoint != null).Select(b => b.EndPoint.Port).Single(); 


       section = new IISSection 
        { 
         ApplicationPoolName = data.App.ApplicationPoolName, 
         VirtualDirectoryAlias = data.App.Path, 
         WebsiteName = data.Website.Name, 
         WebsiteRoot = data.App.VirtualDirectories[0].PhysicalPath, 
         Port = port.ToString(CultureInfo.InvariantCulture), 
         WillApply = true, 
         AnonymousUser = _userService.GetUserByType(UserType.Anonymous) 
        }; 
      } 

      return section; 

     } 

回答

3

没有完全重写你的代码,一般的想法是在ISettingReader *(如IisSettingReader实现),这会暴露,将让你从IIS所需要的数据的方法来传递。然后,您可以在ISettingReader存根返回你所需要的,通过传递ISettingReader到方法/类

*或者IServerManager因为它似乎是目前的名字,但我不知道这是IIS的专门

UPDATE

更具体地讲,因为达林季米特洛夫阐述,你需要把所有的依赖关系的方法之外,并通过参数/构造函数/属性注入超过他们。这将需要重写代码,因为它代表当前状态。

如果不是(我建议重写),那么你可以使用类似TypeMock的东西,它可以伪造类中的依赖关系,但是我没有使用它自己,只知道我读过它。

+1

1,全部重写是必须的,以便提高该代码并打破特定依赖关系到,可以在一个单元测试很容易地嘲笑抽象。 –

+0

ServerManager类是Microsoft.Web.Administration名称空间中的IIS类。 – twreid

+0

另外一个完整的重写不是一个问题。如果这是我需要做的事情,我会做。 – twreid

0

使用Moq

这将允许您创建ISettings的嘲笑版本,而不是创建一个真实的。它还具有允许您指定自己的功能的附加优势。

+1

Moq无法做到这一点,我不认为他在问如何进行单元测试,而是如何使这个具体的单元测试(嘲弄) –

+0

是的,我已经有和使用Moq,我正在寻找想法来提高这个代码使它成为单元可测试的。 – twreid