Pex & Moles with SharePoint – A Quick Example

I recently demoed moles against the SharePoint 2007 object model. I demoed testing a contrived method that simple returned true if the number of items in a SharePoint list was greater than 20. Code is below…

 

private const int ItemsPerPage = 10;

public bool ShowPagination()
{
    using (SPSite siteCollection = new SPSite(“
http://example.local”))
    {
        using (SPWeb web = siteCollection.OpenWeb())
        {
            SPList list = web.Lists[“MyList”];

            if (list.ItemCount > ItemsPerPage)
            {
                return true;
            }
        }
    }

    return false;
}

This is a difficult method to test, as you cannot mock out the SharePoint OM code (as it’s not written to an interface etc). As you are tied to SharePoint, you would need to alter the SharePoint list to test boundary conditions. This is where moles come in…

I generated a mole dll against the Microsoft.SharePoint dll in my test project, and was then able to intercept SharePoint OM calls via lambdas. The example below illustrates a test that force the value of the list.ItemCount to return a known value. Note that in my test, the SharePoint OM was not called, instead only the Mole classes were called (via a detour).

[TestMethod]
[HostType(“Moles”)]
public void ShowPaginationReturnsFalseWhenLessThanTenItems()
{
    // Arrange

    // Use initilizers and lamdba functions to set up moles
    // Only “mole” functionality that is used by code
    MSPSite.ConstructorString = (site, url) => new MSPSite(site)
    {
        OpenWeb = () => new MSPWeb
        {
            ListsGet = () => new MSPListCollection
            {
                ItemGetString = id => new MSPList
                {
                    ItemCountGet = () => 9
                }
            },
            Dispose = () => { }
        },

        Dispose = () => { }
    };

    // Act
    TableLogic tableLogic = new TableLogic();
    bool showPagination = tableLogic.ShowPagination();

    // Assert
    Assert.IsTrue(showPagination == false, “The page will be paginated”);
}

 

http://research.microsoft.com/en-us/projects/pex/

SharePoint 2010: Provisioning a new site using a custom template

In SharePoint 2010, stps are no longer used. Instead site templates are saved as wsp files.

To create a new site collection using one of these template through the UI, you need to create a site collection through central admin that has no template selected. Once completed, browse to the site collection. From here, you are prompted to select a template. Instead of doing this, click the link to “solution gallery” and Upload your wsp file (previously exported). Once complete, go back to the choose template screen (at the root of the site collection) and select you new template from the “custom” tab.

image

Below is some powershell script that facilitates this…

[void][System.Reflection.Assembly]::Load(“Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c”)
New-SPSite -Url “
http://localhost:81/sites/robtest2″ -OwnerAlias “Administrator” -Description “Rob Test Site” -Name “Rob Test” -Language 1033
Add-SPUserSolution -LiteralPath “C:\Users\Administrator\Desktop\RobTestX.wsp” -Site “
http://localhost:81/sites/robtest2″
Install-SPUserSolution -Identity “RobTestX.wsp” -Site “
http://localhost:81/sites/robtest2″
$site = New-Object Microsoft.SharePoint.SPSite(“
http://localhost:81/sites/robtest2″)
$web = $site.OpenWeb();
$template = $web.GetAvailableWebTemplates(1033) | Where-Object {$_.Name -like “{*” }
$templateName = $template.Name
$web.ApplyWebTemplate($templateName)

Quicknote: Extending a VHD

Just a note as I’ve had to extend a fixed size VHD. I used http://code.msdn.microsoft.com/vhdtool to expand the actual VHD file. This extending the partition, but did not extend the volume. To complete the process, I needed to boot the VHD and extend the volume (C:).

As I wanted to extend my boot volume (C:), I could not extend onto this using Disk Management (from Computer Management). Instead I had to use the Diskpart tool (access via the command line when ran as Administrator).

I then ran the following commands:

diskpart (this takes you to the diskpart prompt).

list disk
select disk 2
detail disk
select volume 3
detail volume
extend
detail volume

Once complete, my fixed size VHD was expanded to  60Gb

Related link:

http://www.techotopia.com/index.php/Extending_and_Shrinking_Windows_Server_2008_Partitions_and_Volumes

SharePoint: FormField Control

Just discovered this control the other day. It renders SharePoint field types (and custom field types) as they would appear on a SharePoint form. All you need to pass to it it the id of a list and field name. It can also be used generate a form element in edit mode (i.e. with values populated).

using (var site = new SPSite(“http://mywebsite”))
{
    using (var web = site.OpenWeb())
    {
        var list = web.Lists[this.ListName];

        foreach (SPField field in list.Fields)
        {
            if (field.FieldRenderingControl != null &&
              !field.Hidden && !field.ReadOnlyField &&
              field.Type != SPFieldType.Attachments)
            {
                var currentField = new FormField();
                currentField.ListId = list.ID;
                currentField.FieldName = field.InternalName;
                currentField.ID = “Control_” + field.InternalName;
                currentField.ControlMode = SPControlMode.New;
                this.Controls.Add(currentField);
            }
        }
    }
}

See this article for a longer explanation / more code!

http://www.fivenumber.com/sharepoint-list-form-generator/

Using OM to access Lists in another web app / Random Notes

I had to access a list on a SharePoint web app from another web app on the same farm using code, but experienced a sql exception. The app pool accounts had least privilege, but the accounts of the user had restricted reader rights to both web apps (and app pool account as i tried running with elevated privileges). It turns out that if your executing code against a web app outside of your current context, you need to have rights to the db on the server.

http://blog.krichie.com/2008/09/11/unrestricted-access-via-sharepoint-object-model-from-console-applications/

I ended up reading via webservices and converting to a datatable, similar to the following.

http://politechnosis.kataire.com/2008/09/reading-sharepoint-lists-into-adonet.html

Unrelated, here is a good article on making web.config mods via a feature receiver.

http://weblogs.asp.net/wesleybakker/archive/2009/01/21/web.config-modifications-with-a-sharepoint-feature.aspx

Here is another unrelated article about group policy (something i never fully remember).
http://technet.microsoft.com/en-us/library/cc732593(WS.10).aspx