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
0 votes
Hi,
This is my 1st post here and I dont think it will be last one :lol:

My problem is that i created a mocked SPWeb object and in that object i wanna add an SPList object and some fields. Problem is each time when I debug when I do web.Lists.Count to see if the list is actually added I get 0. whatever method I do the list is not created dunno if Im doing something wrong since i have just started with Typemock ^^. Here is the code it is simple.

            SPWeb web = Isolate.Fake.Instance<SPWeb>(Members.ReturnRecursiveFakes);
            Isolate.Swap.NextInstance<SPWeb>().With(web);

            web.Lists.Add("Liste_Dossier", "This calendar was created programmatically", web.ListTemplates["Calendar"]);
            SPList list = web.Lists["Liste_Dossier"];
            list.Update();

            Console.WriteLine("aaaaaaa");


The Console.WriteLine I just added it to breakpoint at it for debugging purposes. Thank you in advance .
asked by Rasenganguy (720 points)

9 Answers

0 votes
Hi and Welcome to our forums!

Faking list behavior is a bit more complex than faking straightforward methods - lists (collections in general) mix state and behavior that would take a bit of work to fake explicitly. In Isolator we provide a mechanism to replace your collection with any test data collection - this way you can control the collection the code under test will access, and you can be assured that the collection's complete behavior refers to the test data. This is done using the WhenCalled().WillReturnCollectionValuesOf() method:
var fakeListItem1 = Isolate.Fake.Instance<SPListItem>();
var fakeListItem2 = Isolate.Fake.Instance<SPListItem>();
var testData = new SPListItem[] { fakeListItem1, fakeListItem2 };
Isolate.WhenCalled(() => web.Lists["List"]).WillReturnCollectionValuesOf(testData);


Another way to control the behavior of collections, is to go ahead and set the behavior of the list items. A backing list will be automatically populated for your use:
Isolate.WhenCalled(() => web.Lists["List"][0].Name).WillReturn("Name1");
Isolate.WhenCalled(() => web.Lists["List"][2].Name).WillReturn("Name3");


:!: The backing list created in this technique will always be large enough to iterate through - in this case list items 0 and 2 will have specific behavior set on their Name property, and item 1 is automatically created as a recursive fake.
:!: You can find examples to similar scenarios in SharePoint in our SharePoint example solution - check it out under the program files shortcut group that was installed with Isolator.
:!: Final quick tip - you can drop the Members.ReturnRecursiveFakes when creating a fake instance - ReturnRecursiveFakes is the default behavior for Fake.Instance.

I hope this helps - please follow up and let me know if my description above answered all your questions. Welcome again to Isolator - let us know if you need anything else.

Doron
Typemock Support
answered by doron (16.5k points)
0 votes
Yeah I read that on the doc of Typemock and tbh it is really sweet it save a lot of time. But it wont work for my case. Actually Im trying to test a feature event and I do not know the way how to use Typemock to test features events here is the code.


public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            Common.WriteErrorLog(MstrKeyChk, "DesActivation of feature IntranetSuresnes.AddLookUp");
            using (SPWeb web = properties.Feature.Parent as SPWeb)
            {
                if (web != null)
                {
                    try
                    {
                        SPList listeDossier = web.Lists["Liste_Dossier"];

                        if (listeDossier != null)
                        {
                            if (listeDossier.Fields.ContainsField("Liens"))
                            {
                                listeDossier.Fields.Delete("Liens");
                                listeDossier.Update();
                            }
                        }
                    }
                    catch (SPException ex)
                    {
                        Common.WriteErrorLog(MstrKeyChk, "Erreur dans l'ajout du champ aux listes de Dossiers: " + ex.Message);
                    }
                }
            }
        }


It is fairly simple it just check if there is a specific field name when the feature is deactivating if so it deletes it I tried to devide the code because I really dont know how to test feature event. Thats why I tried to fake a list with a field to see if that field will be deleted later. Using the method you said will never allows me to delete the field since it is not really there. I hope I was clear in my explanation and thx in advance :D
answered by Rasenganguy (720 points)
0 votes
up :oops:
answered by Rasenganguy (720 points)
0 votes
Hi,

In order to verify the a call was made you can use the Verify methods.

For example:
public class ClassUnderTest
{
    public void FeatureDeactivating(SPWeb web)
    {
        SPList listeDossier = web.Lists["List"];
        listeDossier.Fields.Delete("Item");
    }
}

[TestClass]
public class TestsClass
{
    [TestMethod]
    public void VerifyFieldWasDeleted()
    {

        SPWeb web = Isolate.Fake.Instance<SPWeb>();
        var fakedSPList = Isolate.Fake.Instance<SPList>();
        Isolate.WhenCalled(() => web.Lists["List"]).WillReturn(fakedSPList);
        
        var classUnderTest = new ClassUnderTest();
        classUnderTest.FeatureDeactivating(web);
        
        Isolate.Verify.WasCalledWithExactArguments(() => fakedSPList.Fields.Delete("Item"));
    }
}

This example code verified that the Delete method was called during the test execution and it also verifies the arguments that were used.

It is also possible to verify the any field was deleted without verifying which using 'WasCalledWithAnyArguments'. For example:
Isolate.Verify.WasCalledWithAnyArguments(() => fakedSPList.Fields.Delete(null));

This example makes sure the method was called without verifying with which arguments it was actually called.

Best Regards,
Elisha
Typemock Support Team
answered by Elisha (12k points)
0 votes
Hi Elisha,

OMG it is so simple I was thinking same but I said that it couldnt be that simple Im so dump complicating my life :lol: .

Thank you a lot I got the idea now.
answered by Rasenganguy (720 points)
0 votes
Hi,

I have following code for which I want to write a unit test using TypeMock:

        public static void CreateList(SPWeb web, string listName)
        {
            SPList list = GetList(web, listName);
            if (list == null)
            {
                Guid listGuid = web.Lists.Add(listName, "", SPListTemplateType.GenericList);
                list = web.Lists[listGuid];
                list.OnQuickLaunch = true;
                list.Update();
            }
        }

        public static SPList GetList(SPWeb web, string listName)
        {
            SPList list = null;
            try
            {
                list = web.Lists[listName];
            }
            catch (Exception ex)
            {
                list = null;
            }

            return list;
        }


and following is the test code:
        [TestMethod()]
        [Isolated]
        public void CreateListTest_ListNotExists_ListCreated()
        {
            //Arrange
            var fakeSite = Isolate.Fake.Instance<SPSite>(Members.ReturnRecursiveFakes);
            Isolate.Swap.NextInstance<SPSite>().With(fakeSite);

            var fakeWeb = fakeSite.OpenWeb();
            string listName = "TestList";
            Isolate.WhenCalled(() => fakeWeb.Lists[listName]).WillReturn(null);

            //Act
            Common.CreateList(fakeWeb, listName);
            
            //Assert
            //Isolate.Verify.WasCalledWithArguments(() => fakeWeb.Lists[listName].Title = listName);
            //Isolate.Verify.WasCalledWithArguments(() => fakeWeb.Lists[listName].Update());
            //Isolate.Verify.WasCalledWithArguments(() => fakeWeb.Lists.Add(listName, "", SPListTemplateType.GenericList));
   //what should I call here to verify            
        }


Can anybody help me to complete the above unit test code?

Thanks,
Muhammad Masood.
answered by mmasood_typemock (180 points)
0 votes
Hi,

In order to complete the assert, it's possible to check the list state.
For example:
Assert.AreEqual(listName, fakeWeb.Lists[listName].Title)


A clarification about Verify, in order to make sure a call was made with exact arguments this API can be used:
Isolate.Verify.WasCalledWithExactArguments(() => myObject.Method(arg1, arg2));


The WasCalledWithArguments API is used for custom verification - the call needs to be completed with Matching(args => ...) which is a predicat for the calls made on the object.

Please let me know if it helps.

Regards,
Elisha,
Typemock Support
answered by Elisha (12k points)
0 votes
Hi,

I used Assert.AreEqual(listName, fakeWeb.Lists[listName].Title)
and it is failing.

when I debug the fakeWeb.Lists collection I could not see anything I supplied to create the list.

Is there any other way to test above code?

Thanks,
Muhammad Masood.
answered by mmasood_typemock (180 points)
0 votes
Hi Muhammad,

It seems that you need to use the Isolate.Verify.WasCalledWithExactArguments API. So your test will look like this:

[TestMethod, Isolated]
public void CreateListTest_ListNotExists_ListCreated()
{
    //Arrange
    var fakeSite = Isolate.Fake.Instance<SPSite>(Members.ReturnRecursiveFakes);
    Isolate.Swap.NextInstance<SPSite>().With(fakeSite);
    
    var fakeWeb = fakeSite.OpenWeb();
    
    string listName = "TestList";
    Isolate.WhenCalled(() => fakeWeb.Lists[listName]).WillReturn(null);

    //Act
    Common.CreateList(fakeWeb, listName);

    //Assert
    Isolate.Verify.WasCalledWithExactArguments(() => fakeWeb.Lists.Add(listName, "", SPListTemplateType.GenericList));
    Guid fakeGuid = new Guid();
    Isolate.Verify.WasCalledWithAnyArguments(() => fakeWeb.Lists[fakeGuid].Update());
}


:arrow: For sake of the examples I used two flavors of the verify API. The first will pass only if fakeWeb.Lists.Add was called with the exact arguments as in the verify line. i.e.
"TestList", "", SPListTemplateType.GenericList
In the second I just want to check that list.Update method was called and I don't care about the arguments.

:arrow: I also suggest to use one assert per test. If the tests will fail in the future for some reason it will be easier to find the reason.

Please let me know if it helps.
answered by ohad (35.5k points)
...