November Happy Hour will be moved to Thursday December 5th.

unit testing creating a block programmatically

Vote:
 

Hi,

I'm writing unit tests where I need to create a block programmatically and then adds it to a content area on a commerce product/variant page.  It looks something like this when creating the block before adding it to a content area:

var imageBlock = contentRepository
.GetDefault(parentFolder);

imageBlock.Image = image;
imageBlock.AlternativeText = name;

var content = imageBlock as IContent;



The above works, but when I run my unit tests, content is null when I try to cast it to IContent.  I'm aware that EPiServer creates proxy objects for shared blocks in runtime.  I'm not sure how to get pass this or how to change my code.

Thanks

#119817
Apr 03, 2015 10:34
Vote:
 

What do you do later with IContent? Do you access any specific properties out of that interface? You can take a look at SharedBlockFactory.CreateSharedBlock(Type). Factoy has long list of dependnecies - so you may have to setup lot of things to get proper functionality out.

But basically - when shared blocks are created proxy class is created manually.

#119868
Apr 04, 2015 22:19
Vote:
 

Thanks Valdis - After creating the block I need to get the content refernce.  That content reference is used to link the block to a content area.

#119885
Apr 06, 2015 19:41
Vote:
 

Just stepping one step back..

What is your main goal for unit test? What functionality are you going to cover in that test?

#119888
Apr 06, 2015 21:58
Vote:
 

Hello Danie

It may be worth reading this article: http://world.episerver.com/Blogs/Johan-Bjornfot/Dates1/2012/11/Shared-blocks--IContent/

Looking at the example code I think you may need to save the block before loading it from the content repo to get the IContent reference. 

Let me know how it goes.

David

#119903
Edited, Apr 07, 2015 11:01
Vote:
 

Actually yes, ContentRepository should call shared block factory anyway under the hood - so returned object instance should be of type IContent as well. Anything special maybe about unit test setup?

#119912
Apr 07, 2015 12:50
Vote:
 

Hi guys,

thanks for your replies

I've written a plugin for the editors to upload multiple images into the asset manager, then create a block for each image and then to link all the image blocks to a content area for a page.

The code below works, but its fails when I try to unit test it.

var imageBlock = baseDependencies
.ContentRepository
.GetDefault<ImageBlock>(parentFolder);

imageBlock.Image = image;
imageBlock.AlternativeText = name;

var content = imageBlock as IContent;

content.Name = name;

baseDependencies.ContentRepository
.Save(content,
SaveAction.Publish,
AccessLevel.NoAccess);


For my unit test I would like to to run through the code first without it throwing an exception.  But currently its failing because content is null when I cast it to IContent.  Once I get my unit test just to run through the code I want to test if the "Save" function is called creating the block.

I'm not sure how to setup my unit test or code so that I can cast the block to IContent without it being null.

Thanks,

Danie

#119928
Apr 07, 2015 18:56
Vote:
 

But I guess I can change the code to retrieve the IContent from the repo after saving it.

#119929
Apr 07, 2015 19:03
Vote:
 

How did you setup unit test that line zero (where you receive instance of repository) will not throw an exception?

#119955
Apr 07, 2015 22:09
Vote:
 

I've changed the code a bit:

return baseDependencies.ContentRepository
.Save(content,
SaveAction.Publish,
AccessLevel.NoAccess);

The setup for the content repository for unit test:

ContentRepositoryMock.Setup(x => x.Save(It.IsAny<IContent>(), SaveAction.Publish, AccessLevel.NoAccess))
.Returns(blockContentReference)



#119961
Apr 08, 2015 9:46
Vote:
 

Who is "ContentRepositoryMock"? I just speculate that you are mocking content repository in a way that it actually will not produce IContent as result of "GetDefault()" :)

#119963
Apr 08, 2015 10:03
Vote:
 

I think I know where I'm going wrong..

ContentRepositoryMock.Setup(x => x.GetDefault<ImageBlock>(folder.ContentLink)).Returns(GalleryImageBlock);

The above is my setup for GetDefault (yes, ContentRepository is the the content repository mock)

I think I should return an IContent object instead of an ImageBlock for the test.  But if I setup the GetDefault to return an IContent object I can't compile my code because the return type needs to be of type ImageBlock.

var content = new Mock<IContent>();
ContentRepositoryMock.Setup(x => x.GetDefault<ImageBlock>(folder.ContentLink)).Returns(content.Object);



#119964
Apr 08, 2015 10:18
Vote:
 

Yes, this is the issue. If you want to return object that you can cast to IContent, you need to take a look at SharedBlockFactory. You have to produce mixin, create proxy and then return it. A bit more to setup.

#119976
Apr 08, 2015 11:51
This thread is locked and should be used for reference only. Please use the Episerver CMS 7 and earlier versions forum to open new discussions.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.