sshushliapin / Sitecore.FakeDb

Unit testing framework for Sitecore.
MIT License
117 stars 36 forks source link

Question: How to mock retrieving media URL from an image field? #193

Closed dumbo0001 closed 6 years ago

dumbo0001 commented 6 years ago

I can't figure out how to write a test for the retrieval of a media URL from an item with an image field. I'm using the MediaManager and the example to mock the MediaProvider.

ImageField field = item.Fields["TheImageField"];
var url = MediaManager.GetMediaUrl(field.MediaItem);

Any suggestions?

pveller commented 6 years ago

I am assuming that you looked at the example here: https://github.com/sergeyshushlyapin/Sitecore.FakeDb/wiki/Media correct? Can you please post your entire test so we could reproduce?

sshushliapin commented 6 years ago

The first suggestion is to use new Sitecore's BaseMediaManager class (if you're on SC 8.2+). That's valid for all the managers.

You should be able to achieve what you need using FakeDb's MediaProviderSwitcher but youl should keep in mind that all the provider switchers stop working in SC9.0, so the first option is more preferable.

dumbo0001 commented 6 years ago

I' having a class which reads an image field from an item and returns the image/media URL. Example:

public class GetItemImage
    {
        public string GetImage(Item item)
        {
            ImageField imageField = item.Fields["ItemImage"];

            if (imageField?.MediaItem == null)
            {
                return string.Empty;
            }

            return MediaManager.GetMediaUrl(imageField.MediaItem);
        }
    }

And the unit test:

[Fact]
        public void Should_retrieve_media_url_from_image_field()
        {
            ID mediaItemId = ID.NewID;
            ID itemID = ID.NewID;

            // create some media item. Location, fields and template are not important
            using (var db = new Db
            {
                new DbItem("my-image", mediaItemId),
                new DbItem("Item A", itemID)
                {
                    new DbField("ItemImage")
                    {
                        Value = mediaItemId.ToString()
                    }
                }
            })
            {
                var fakeMediaProvider = A.Fake<MediaProvider>();
                A.CallTo(() =>
                     fakeMediaProvider.GetMediaUrl(
                         A<MediaItem>.That.Matches(item => item.ID.ToString() == mediaItemId.ToString())))
                 .Returns("http://tempuri.org/image-url");

                // substitute the original provider with the mocked one
                using (new Sitecore.FakeDb.Resources.Media.MediaProviderSwitcher(fakeMediaProvider))
                {
                    Item item = db.GetItem(itemID);
                    var getItemImage = new GetItemImage();

                    string result = getItemImage.GetImage(item);

                    Xunit.Assert.Equal("http://tempuri.org/image-url", result);
                }
            }
        }

I think I'm missing something to state that the field of the item is an ImageField. I'm using FakeItEasy for mocking.

dumbo0001 commented 6 years ago

Nevermind. You always need to ask first and then you'll find the answer by yourself. The way I've added the image field was wrong. Test succeeded after changing the test to:

[Fact]
        public void Should_retrieve_media_url_from_image_field()
        {
            ID mediaItemId = ID.NewID;
            ID itemID = ID.NewID;

            // create some media item. Location, fields and template are not important
            using (var db = new Db
            {
                new DbItem("my-image", mediaItemId),
                new DbItem("Item A", itemID)
                {
                    { "ItemImage", $"<link linktype=\"media\" mediaid=\"{mediaItemId.ToString()}\" />" }
                }
            })
            {
                var fakeMediaProvider = A.Fake<MediaProvider>();
                A.CallTo(() =>
                     fakeMediaProvider.GetMediaUrl(
                         A<MediaItem>.That.Matches(item => item.ID.ToString() == mediaItemId.ToString())))
                 .Returns("http://tempuri.org/image-url");

                // substitute the original provider with the mocked one
                using (new Sitecore.FakeDb.Resources.Media.MediaProviderSwitcher(fakeMediaProvider))
                {
                    Item item = db.GetItem(itemID);
                    var getItemImage = new GetItemImage();

                    string result = getItemImage.GetImage(item);

                    Xunit.Assert.Equal("http://tempuri.org/image-url", result);
                }
            }
        }

Please correct me if it is not intended to be like this. I'm closing this issue.