I use moles to write unit tests on hard-to-reach parts of my code, especially when I use types found in sitecore class libraries (which are hard to use mocking frameworks with). I ran into a surprisingly difficult problem when Im trying to unwind a LinkField type and test the following kind of code snippet.
LinkField linkField = item.Fields["External Url"]; if (linkField.IsInternal && linkField.TargetItem != null) {
item.Fields is a collection of fields whose index returns the type SiteCore.Data.Field, but the LinkField is configured in such a way that it uses an implicit operator that hides the conversion, which means that you can work with the LinkField instance in your code.
My difficulty is that I cannot create a mole of type MLinkField and assign it to FieldCollection in Item, since it is strongly typed for Field. Moreover, it seems that although I can create an MField type when an implicit conversion occurs, it will work and return an object, but none of the fields have any values. This means that I cannot check the code path above, which depends on the state of the linkField property defined in a certain way.
The only way I can think of setting these values indirectly is to search for which values to set by analyzing the implicit conversion and setting them to MField. The implicit statement calls the LinkField constructor as follows:
public LinkField(Field innerField) : base(innerField, "link")
which means that I need to be aware of how it creates the base type (XmlField) and, in turn, this base class type (CustomField). Then, to see what basic values TargetItem is looking for. The end result is the need to extort:
InnerField.Database.Items[internalPath];
or
InnerField.Database.Items[targetID];
Where InnerField is effectively my MField.
Anyone have a better idea? It sounds terribly confusing, but I think the nature of the beast is with these collections.