【问题标题】:How to unit test static method which is used in the razor view?如何对剃刀视图中使用的静态方法进行单元测试?
【发布时间】:2023-03-18 16:50:01
【问题描述】:

假设我有一个具有以下扩展方法的静态类,它从缓存中检索文件或从磁盘读取文件,如果不存在则将其放入缓存中 + 对内容进行一些更改(例如,添加标签或属性):

public static class Foo
{
  public static DoSomething(this HtmlHelper helper, string url, List<string> parameters)
  {
     string content = String.Empty;
     var cache = HttpContext.Current.Cache[url];

     if (cache == null)
     {
       string absolute_path = WebPages.HelperPage.Server.MapPath(url);
       content = File.ReadAllText(absolute_path);
       HttpContext.Current.Cache.Add(url, content, ...);
     }
     else
     {
       content = cache.ToString();
     }

     //make a few changes to content (e.g., add some tags or attributes)
     content = makeChangesToContent(content, parameters);

     return MvcHtmlString.Create(content);
  }
}

此方法在剃刀视图中使用如下:

   @Html.DoSomething("/path/to/file", new List<string>(){"param1", "param2"});

为了使这段代码可测试,我必须从方法中删除所有依赖项。但由于它是静态的并且在剃刀视图中使用,所以我不确定如何正确操作。

我想到的唯一一个选择是使用 Shims 通过一些伪造的方法来伪造外部依赖项。但是单元测试代码看起来有点重,运行大约需要200ms。

这是单元测试的一个简单示例:

[Test]
public void DoSomething_Should_Return_FileContent_From_Cache_When_It_Is_There()
{
    string relativeFilePath = "/some/path";
    string fileContent = "content";
    string cachedKey = String.Empty;
    object cachedValue = null;

    using (ShimsContext.Create())
    {
        //Arrange
        System.Web.Fakes.ShimHttpContext.CurrentGet = () =>
        {
            var httpContext = new System.Web.Fakes.ShimHttpContext();

            httpContext.CacheGet = () =>
            {
                var cache = new System.Web.Caching.Fakes.ShimCache();

                cache.ItemGetString = (key) =>
                {
                    cachedKey = key;
                    cachedValue = fileContent;

                    return fileContent;
                };

                return cache;
            };

            return httpContext;
        };

        //Act
        var result = helper.DoSomething(relativeFilePath, new List<string>(){"param1", "param2"});

        //Assert
        Assert.IsTrue(cachedKey.Equals(relativeFilePath));
        Assert.IsTrue(cachedValue.Equals(fileContent));
    }

测试方法是否正确?有没有更好的选择? 根据您的经验,测试此类静态方法的最佳方法是什么?

【问题讨论】:

标签: c# asp.net-mvc unit-testing razor static-methods


【解决方案1】:

HtmlHelpers 应该用于为视图输出 Html。

这里有一个很好的解释Why do we use HTML helper in ASP.NET MVC?

您编写的助手看起来应该在控制器动作中。像

public class ScratchController : Controller
{
    private readonly IProvideFilePath _pathProvider;
    private readonly IProvideCacheSupport _cacheProvider;
    public ScratchController(IProvideFilePath pathProvider, IProvideCacheSupport cacheProvider)
    {
        _pathProvider = pathProvider;
        _cacheProvider = cacheProvider;
    }

    [HttpPost]
    public FileResult Index(string url, List<string> parameters)
    {
        var fileContent = _cacheProvider.GetItem(url) as string;  
        if (string.IsNullOrWhiteSpace(fileContent))
        {
            var filePath = _pathProvider.MapPath(url);

            fileContent = File.ReadAllText(filePath);
            _cacheProvider.AddItem(url, fileContent);
        }

        fileContent = makeChangesToContent(fileContent, parameters);

        return Content(fileContent);
    }
}

其中 IProviderFilePath 位于包装 Server.MapPath 调用的类前面,而 ​​IProvideCacheSupport 位于包装对 Cache 调用的类前面。这样你就可以同时模拟两者。

【讨论】:

    【解决方案2】:

    你的方法太多了,我把它分开:

    public class GetFileController
    {
      public string GetFileContent(string url)
      {
        //Read file from disk & return content
      }
    
      public string GetCachedFileContent(string url, Cache cache)
      {
        if(!cache.ContainsUrl)
          cache[url] =  GetFileContent(url);
        return cache[url];
      }
    }
    
    public class MakeChangesController()
    {
      public string DoChanges(){}
    }
    

    然后您可以模拟文件读取并测试您所做的更改,而无需从磁盘读取。

    【讨论】:

      猜你喜欢
      • 2016-01-30
      • 2011-11-01
      • 2020-09-06
      • 1970-01-01
      • 1970-01-01
      • 2018-08-30
      • 2017-02-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多