繁体   English   中英

如何在单元测试中模拟伪造的 TreeNode 的 Parent 访问器?

[英]How can I mock the Parent accessor of a faked TreeNode in a unit test?

使用 Kentico 12 SP,修补程序 64 - 我可以创建伪造的TreeNode类型并在大多数字段上设置值,但我无法为Parent设置返回值,我需要这样做才能对方法进行测试。

我试图测试的方法:

public Dictionary<string, string> GenerateBreadcrumbs(TreeNode treeNode)
{
    var breadcrumbs = new Dictionary<string, string>();
    if (treeNode != null) {
        var revBreadcrumbs = new Dictionary<string, string>();
        var thisNode = (treeNode.Parent != null && treeNode.Parent.NodeAliasPath != "/") ? treeNode.Parent : null;
        while (thisNode != null) {
            revBreadcrumbs.Add(thisNode.DocumentName, thisNode.NodeAliasPath.ToLowerInvariant());
            thisNode = (thisNode.Parent != null && thisNode.Parent.NodeAliasPath != "/") ? thisNode.Parent : null;
        }
        foreach (var item in revBreadcrumbs.Reverse())
        {
            breadcrumbs.Add(item.Key, item.Value);
        }
    }
    return breadcrumbs;
}

在单元测试中,我可以伪造文件类型的文档类型

DocumentGenerator.RegisterDocumentType<Folder>(Folder.CLASS_NAME);
Fake().DocumentType<Folder>(Folder.CLASS_NAME);

我可以创建实例并在其他属性上设置值,它们按预期工作

Folder baseFolder = TreeNode.New<Folder>()
    .With(f => f.SetValue("DocumentName", docName))
    .With(f => f.SetValue("NodeAliasPath", docPath));

但是当我尝试为“Parent”设置返回值时,它会在被测试的方法调用时忽略该值。

Folder underFolder= TreeNode.New<Folder>()
    .With(f => f.SetValue("Parent", baseFolder));

我尝试使用 NSubstitute 来更改Parent underFolder.Parent.Returns(baseFolder);的返回值underFolder.Parent.Returns(baseFolder); 但它抛出异常"NSubstitute.Exceptions.CouldNotSetReturnDueToNoLastCallException : Could not find a call to return from." .

对此错误的搜索似乎表明我没有以 NSubstitute 预期的方式伪造类,这将是这样的: var mockFolder = Substitute.For<Folder>(); 我也尝试了 Moq 版本,两者都返回错误System.TypeLoadException : Method 'DeleteInternal' on type 'Castle.Proxies.FolderProxy' from assembly 'DynamicProxyGenAssembly2...表明 TreeNode 的一个或多个属性不能被嘲笑框架......呃。

无论如何,我应该使用不同的策略来测试这个吗? 我不想为 TreeNode 编写一个包装器,但似乎我可能不得不进行测试?

我不认为这在单元测试中是可能的。

TreeNode.Parent不是由数据库字段支持的字段/原始值(即使NodeParentID是),因此使用.SetValue()不会产生任何影响。

在源代码中, TreeNode.Parent属性至少进行 1 次数据库查询(可能是 2 次),并且 Kentico 单元测试基础结构都不会处理这些查询。

我的建议是使用 2 个选项中的一个。

  1. 通过使用抽象从TreeNode获取其值来隔离您对TreeNode.Parent的使用,然后使用NSubstitute类的NSubstitute (或手动)在您的测试中创建一个存根。
public interface ITreeNodeAccessor
{
    TreeNode GetParent(TreeNode node);
}
  1. 切换到集成测试

当单元测试基础设施无法处理我的用例时,我个人采用了两种方法 - 我采用的方法取决于我实际尝试测试的内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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