chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
Welcome to Typemock Community! Here you can ask and receive answers from other community members. If you liked or disliked an answer or thread: react with an up- or downvote.
0 votes
Hi there,

I am trying out Isolator and so far loving it!

The method I would like to test looks like this:

public void MapItems(SPListItemCollection itemCollection)
{
foreach (SPListItem item in itemCollection)
{
//Do something
}
}


I have created a fake SPListItemCollection - but I can't work out how to fake the behaviour for the line

foreach (SPListItem item in itemCollection)


What I'd like is for an exception to be thrown when the statement above is executed. I found that with SPQuery, if the query is invalid (e.g. referring to a field that does not exist) then the exception is thrown not on SPList.GetItems(), but rather when the SPListItemCollection is accessed, e.g. in a foreach statemeetnt.

The other thing I need to fake is to add a couple of SPListItem to this collection.

How can these things be done?

Thanks!
asked by u991386 (600 points)

6 Answers

0 votes
Thank you for the kind words,

If you need to throw exception while iterating a collection I suggest using Isolate.NonPublic to fake the enumerator and it's behavior:
var sc = new SharepointUsingClass();
var collection = Isolate.Fake.Instance<SPListItemCollection>();
var enumarator = Isolate.Fake.Instance<IEnumerator>();
Isolate.WhenCalled(() => enumarator.MoveNext()).WillThrow(new Exception("Some Exception"));

Isolate.NonPublic.WhenCalled(collection, "System.Collections.IEnumerable.GetEnumerator")   .WillReturn(enumarator);

sc.MapItems(collection);

Setting actual items can be done along with a feature we call sequencing - setting fake on the same call multiple times:
var sc = new SharepointUsingClass();
var collection = Isolate.Fake.Instance<SPListItemCollection>();
var enumarator = Isolate.Fake.Instance<IEnumerator>();

var fakeItem1 = Isolate.Fake.Instance<SPListItem>();
var fakeItem2 = Isolate.Fake.Instance<SPListItem>();
var fakeItem3 = Isolate.Fake.Instance<SPListItem>();

Isolate.WhenCalled(() => enumarator.MoveNext()).WillReturn(true);
Isolate.WhenCalled(() => enumarator.Current).WillReturn(fakeItem1);
Isolate.WhenCalled(() => enumarator.MoveNext()).WillReturn(true);
Isolate.WhenCalled(() => enumarator.Current).WillReturn(fakeItem2);
Isolate.WhenCalled(() => enumarator.MoveNext()).WillReturn(true);
Isolate.WhenCalled(() => enumarator.Current).WillReturn(fakeItem3);
Isolate.WhenCalled(() => enumarator.MoveNext()).WillReturn(false);// last item

Isolate.NonPublic.WhenCalled(collection, "System.Collections.IEnumerable.GetEnumerator")
    .WillReturn(enumarator);

sc.MapItems(collection);
answered by dhelper (11.9k points)
0 votes
when i do the same for the following code i get typemock exception. can anyone please help me.
TypeMock.TypeMockException :
*** Cannot mock unsupported types from mscorlib assembly. See supported types here: https://www.typemock.com/mscorlib-types
at g3.a(Type A_0, Constructor A_1, Object A_2, Boolean A_3)

            var collection1 = Isolate.Fake.Instance<System.ServiceModel.Description.ServiceEndpointCollection>();
            var enumarator = Isolate.Fake.Instance<IEnumerator>();
            var serviceEndpoint1 = Isolate.Fake.Instance<System.ServiceModel.Description.ServiceEndpoint>();
            var serviceEndpoint2 = Isolate.Fake.Instance<System.ServiceModel.Description.ServiceEndpoint>();
            Isolate.WhenCalled(() => enumarator.MoveNext()).WillReturn(true);
            Isolate.WhenCalled(() => enumarator.Current).WillReturn(serviceEndpoint1);
            Isolate.WhenCalled(() => enumarator.MoveNext()).WillReturn(true);
            Isolate.WhenCalled(() => enumarator.Current).WillReturn(serviceEndpoint2);
            Isolate.WhenCalled(() => enumarator.MoveNext()).WillReturn(false);

Isolate.NonPublic.WhenCalled(collection, "System.Collections.IEnumerable.GetEnumerator").WillReturn(enumarator);
Code continuation...
            Isolate.WhenCalled(() => wsdl.ImportAllEndpoints()).WillReturn(collection1);
answered by pavan.kumar (140 points)
0 votes
Hi Kumar,

I tried your code on our latest build and it seems to be working.

Please Download this patch from here and let me know if it helps.
answered by alex (18k points)
0 votes
I am trying the codes in this post but received the following exception at the line "Isolate.WhenCalled(() => fakeTaskList.GetItems(string.Empty)).WillReturn(listCollection);". I am using VS2012 Test Project + Isolator v7.5.1.0 +SharePoint 2013.


TypeMock.TypeMockException :
*** No method with name System.Collections.IEnumerable.GetEnumerator in type Microsoft.SharePoint.SPListItemCollection exists.

at fs.b(Type A_0, String A_1, Type A_2, Type[] A_3)
at c3.a(Object A_0)
at c3.WillReturn(Object value)
at PwC.TTC.TEC.UnitTests.DALUnitTest.GetEngagementMetricsByStatus_Get50_20_20() in d:local_folderMain_Sourcebcbc.UnitTestsbc-UnitTest.cs:line 72
answered by minghung (180 points)
0 votes
Hi,

We're looking into this.
I'll update you ASAP.
answered by alex (18k points)
0 votes
I solved the problem by replacing "System.Collections.IEnumerable.GetEnumerator" with just "GetEnumerator". No more run-time error.

BTW, I also just learned to use WillReturnCollectionValuesOf() to replace both fakeCollection and enumerator implemention. This solves the problem when you need to iterate collection multiple times (ex. inner loop).

ex. Isolate.WhenCalled(() => _myList.GetItems(string.Empty)).WillReturnCollectionValuesOf(new List<SPListItem> { fakeItem1, fakeItem2 });
answered by minghung (180 points)
...