【问题标题】:How to effectively test SiteCore LinkField如何有效地测试 SiteCore LinkField
【发布时间】:2012-10-25 12:00:37
【问题描述】:

我一直在使用 moles 对代码中难以触及的部分编写单元测试——尤其是在我使用 sitecore 类库中的类型(这些类型很难与 mocking 框架一起使用)的情况下。我遇到了一个令人惊讶的棘手问题,我正在尝试使用 LinkField 类型并测试以下类型的代码 sn-p。

LinkField linkField = item.Fields["External Url"];

if (linkField.IsInternal && linkField.TargetItem != null)
{
// want to test this path

item.Fields 是一个字段集合,其索引器返回 SiteCore.Data.Field 类型,但 LinkField 设置为使用隐式运算符隐藏转换,这意味着您可以使用 LinkField 的实例你的代码。

我的困难是我无法创建 MLinkField 类型的摩尔,并将其分配给 Item 中的 FieldCollection,因为它是强类型的 Field。此外,似乎虽然我能够创建一种 MField,但当隐式转换发生时,它将工作并返回一个对象,但没有一个字段被设置为具有任何值。这意味着,我无法测试上面的代码路径,它依赖于以某种方式设置的 linkField 的状态。

我能想到设置这些值的唯一方法是间接的——即通过分析隐式转换并在 MField 中设置这些值来找到需要设置的值。隐式运算符调用 LinkField 构造函数如下:

public LinkField(Field innerField) : base(innerField, "link")

这意味着我需要注意它如何实例化基类型 (XmlField),以及该类的基类型 (CustomField)。 然后,查看 TargetItem 正在寻找的基础值。最终结果是需要淘汰:

InnerField.Database.Items[internalPath];

或者

InnerField.Database.Items[targetID];

InnerField 实际上是我的 MField。

有人有更好的主意吗?这听起来非常令人费解,但我认为这就是拥有这些组件的野兽的本性。

【问题讨论】:

    标签: c# sitecore sitecore6 moles


    【解决方案1】:

    就个人而言,我确实尝试将 Sitecore 从不需要直接与其交互的业务逻辑中抽象出来;但是我注意到有些事情需要直接处理,我尽量不要走得太远。如果您花太多时间从逻辑中抽象出 Sitecore,那么在我看来,您最终可能会使利用 Sitecore 有用的某些功能变得更加困难。

    虽然单元测试纯粹主义者可能不同意我的方法,但我将进行使用 Sitecore API 正确实例化项目的单元测试。这样做相当简单,我不久前写过a blog post。那么您唯一的问题是处理测试数据,但使用测试设置创建它并通过测试拆卸将其删除是相当容易的。

    【讨论】:

    • 感谢您的回复。我必须说在单元测试方面我更像是一个“纯粹主义者”。我的一位同事又写了一篇单元测试 Sitecore 文章,可在此处找到:reservoirdevs.wordpress.com/2013/11/27/…
    【解决方案2】:

    可以做到,但您需要跳过几圈才能使其发挥作用。

    首先,有一点背景:

    • LinkField 不像其他一些字段类型那样从 Field 类继承。
    • LinkField 继承自 XmlField,而 XmlField 又继承自 CustomField。
    • CustomField(及其子类型)通过将字段实例传递给构造函数来实例化。
    • 链接字段将其值存储在此字段实例中。
    • 无法将链接字段添加到 FieldCollection,因为它们不是从 Field 继承的。
    • 我们需要添加 LinkField 的 InnerField 属性,而不是添加 LinkField。
    • 当从 FieldCollection 中提取字段并将其分配给 LinkField 时,将执行隐式转换操作。
    • 隐式转换操作通过将选定字段传递给 LinkField 的构造函数来创建一个新的 LinkField。返回的是这个新的 LinkField。

    现在一些代码:

    const string externalUrl = "External Url";
    const string targetItemName = "Target Item";                     
    Field field = new ShimField { IDGet = () => ID.NewID, NameGet = () => externalUrl };
    Item targetitem = new ShimItem { IDGet = () => ID.NewID, NameGet = () => targetItemName };
    LinkField linkfield = new ShimLinkField(field) { IsInternalGet = () => true, TargetItemGet = () => targetitem };                         
    ShimLinkField.ImplicitOpFieldLinkField = (f) => linkfield;
    FieldCollection fields = new ShimFieldCollection { ItemGetString = (name) => linkfield.InnerField };
    Item item = new ShimItem { NameGet = () => "Test Item", FieldsGet = () => fields };
    

    现在来解释一下:

    使上述代码工作的关键是这一行:

    ShimLinkField.ImplicitOpFieldLinkField = (f) => linkfield;
    

    通过 Shimming 隐式转换运算符,我们可以确保在调用以下行时:

    LinkField linkField = item.Fields["External Url"];  
    

    返回一个链接字段,并且它的属性根据您的需要填充。

    【讨论】:

    【解决方案3】:

    由于LinkField 无法以适当的方式模拟,因此必须“按原样”在单元测试中使用它,这意味着您必须同时测试代码和链接字段的实现。

    好消息是,Link 字段是一个XmlField,它使用存储在内部字段值中的 xml 数据进行操作。为了配置链接字段行为,您只需要在值中设置正确的 xml。

    使用Sitecore.FakeDb,您可以轻松地在内存中创建内容并配置您需要的项目和字段。以下代码创建项目 hometargethome 项目有 Url 链接字段,其中 TargetId 指向 target 项目:

      ID targetId = ID.NewID;
    
      using (var db = new Db
        {
          new DbItem("home")
            {
              // Field 'Url' is an internal link which targets the 'target' item
              { "Url", "<link linktype=\"internal\" id=\"{0}\" />".FormatWith(targetId) }
            },
          new DbItem("target", targetId)
        })
      {
        Item item = db.GetItem("/sitecore/content/home");
        LinkField linkField = item.Fields["Url"];
    
        linkField.IsInternal.Should().BeTrue();
        linkField.TargetItem.Should().NotBeNull();
        linkField.TargetItem.Paths.FullPath.Should().Be("/sitecore/content/target");
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-07
      • 2021-12-21
      • 2016-06-01
      • 1970-01-01
      • 2010-12-26
      • 2011-02-06
      • 1970-01-01
      • 2013-07-11
      相关资源
      最近更新 更多