Thursday, September 1, 2011

Versioning JavaScript Files

A common problem web developers face is dealing with versions of JavaScript files (and other resources like CSS file, images etc.)  On the one hand we want to cache the file so that it doesn't get downloaded every time, but on the other hand we need to be able to force the browser to get a new version if the file changes.

My solution is to treat my own JavaScript files differently from the files I include from frameworks such as jQuery.

For framework files I add a version number to the file name e.g. jQuery-1.5.1.min.js. When the framework is updated, I will use a new file with the new version number in its name and the browser will fetch the new file.

For my own files I append a query string to the end of the url that contains a version number. This version number is fetched from the DLL that the controller code runs from. The effect is that each time a new build is deployed, the browser will refetch the JavaScript file, but in between builds it will cache it.

To this end I have two different URL helpers that I use when referencing files as seen below.

<script type="text/javascript" language="javascript" src="<%: Url.Content("~/Content/Scripts/jquery-1.5.1.min.js") %>"></script>
<script type="text/javascript" language="javascript" src="<%: Url.VersionedLink("~/Content/Scripts/General.js") %>"></script>

Thursday, July 28, 2011

Formatting Dates in MVC

When you want to display a value in MVC, for instance a date, that needs to be formatted and may even be null, it can result in a lot of code in the view. For example.
<%: benefit.BenefitCancelledDt.HasValue ? benefit.BenefitCancelledDt.Value.ToString(Constants.SHORTDATE_FORMAT) : "" %>
There is a better alternative. By using data annotations we can do this it in a much shorter for.

Add the following annotation to the property on the model.
[DisplayFormat (DataFormatString = "{0:" + Constants.SHORTDATE_FORMAT + "}")]
public DateTime? BenefitCancelledDt { get; set; }
The view can then be rewritten like this.
<%: Html.DisplayFor (x => x.PolicyBenefits[i].BenefitCancelledDt)%>
Note that I used Html.DisplayFor. The formatting annotation is not used by the other methods like Html.DisplayTextFor. Also note that the expression needs to bind directly to the model and not to a intermediate variable like benefit in the inital code.

Monday, July 25, 2011

Chucking Out the Registry

I have refactored away from the registry I used previously to store the DataAccessAdaptor, UnitOfWork, ServiceHome, etc. I am now using a DataContext class that has references to the other objects (DataAccessAdapterm etc.) but is itself managed by the DI container. So to access the DataAccessAdapter, instead of using

Registry.GetDataAccessAdapter();
you now use

ObjectFactory.GetInstance<IDataContext> ().Adapter;
All the connection and transaction management is now handled by the DataContext as well.

Here are some pieces of the DataContext class.

public class DataContext
    : IDataContext
{
    public ActionProcedures ActionProcedures { get; set; }
    public IRetrievalProcedures RetrievalProcedures { get; set; }
    public DataAccessAdapterBase Adapter { get; set; }

    ...



    public void Clear ()
    {
        // If clear is called while there is still a transaction, the client code has a bug
        if (Adapter != null && Adapter.IsTransactionInProgress)
        {
            throw new Exception ("There is still an active transaction.");
        }

        // First save any changes in UnitOfWork
        if (UnitOfWork != null)
        {
            UnitOfWork.Commit (Adapter, true);
        }

        // Dispose and remove adapter
        if (Adapter != null)
        {
            Adapter.Dispose ();
        }

        ActionProcedures = null;
        RetrievalProcedures = null;
        Adapter = null;

        ...
    }

    public void Initialize (
        DataAccessAdapterBase adapter)
    {
        Adapter = adapter;
        ActionProcedures = new ActionProcedures ();
        RetrievalProcedures = new RetrievalProcedures ();
        
        ...
    }

    public virtual void StartTransaction (
        IsolationLevel isolationLevel,
        string transactionName)
    {
        Adapter.StartTransaction (isolationLevel, transactionName);
    }


    ...
}
The next step would now be to get rid of the DataAccessorHome and ServiceHome completely and simply get the data accessors and services from the DI container directly.

Thanks to Francois and Schalk for their inputs.

Sunday, July 24, 2011

Setting the Date for Testing

I've added the following code to the remoting sink on the remoting server side to enable us to set the date on the server for automated ui testing.
if (!string.IsNullOrWhiteSpace (ConfigurationManager.AppSettings["Date"]))
{
    ObjectFactory.GetInstance<IDataContext> ().ServiceHome.DateService.SetDate (Utils.ParseDateTime (ConfigurationManager.AppSettings["Date"]));
}
Please make sure this setting never gets set on the production environment.

Thursday, July 14, 2011

Automatic Database Script Execution

We are using an automatic database script execution mechanism such as the one recommended by Scott Ambler.  The basic working of it is that every database refactoring is placed in its own script file and that each file has a sequence number.  We also store the sequence number of the last run script in a table called Version along with a column called DatabaseName that we can query to find out which database we are running the script against.

When the automated deployment takes place, our PowerShell script will automatically run all the scripts since the last one that was run against that database and update the version number.

During an automated build, we actually create the entire unit test database from scratch with a few initialization scripts and then apply all the update scripts in sequence to arrive at the latest database schema.

We also have a script that we us when we download a production database to our development machines, to bring that database up to speed with the latest scripts to match our code.

I recently had an issue where I needed to create a stored procedure on the unit test database that I didn't want in production.  This procedure wipes all the data in the database except lookup data.  I needed this when using recorded tests from Selenium, because unlike our other tests, we can't do the entire test in one transaction and I needed to clean up after the test.

In order to achieve this I used some dynamic SQL like so (thanks for the tip Schalk):
if dbo.GetDatabaseName () = 'policy-unittests'
BEGIN

    DECLARE @Sql NVARCHAR(MAX)
    SET @Sql = 
    'CREATE PROCEDURE CleanDatabase
    AS

        -- Lots of delete statements
        DELETE FROM Policy
        DELETE FROM Person'
        
    EXECUTE sp_executesql @Sql

END

Adding Convenience Methods to Classes

Code can often be simplified by adding a few convenience methods to our classes. For instance, one set of classes were littered with code like this:
CommandInitDataEntity data = CommandEntity.InitDatas.SingleOrDefault (x => x.Key == InitDataKeys.MoiBliscyUpgradeType.ToString ());
if (data != null)
{
    this.UpgradeType = (UpgradeType) Enum.Parse (typeof (UpgradeType), data.Value);
}
I added the following convenience methods to the CommandEntity class:
public bool HasInitData (
    string key)
{
    return this.InitDatas.ToList ().Exists (x => x.Key == key);
}

public bool HasInitData (
    Enum key)
{
    return HasInitData (key.ToString ());
}

public string GetValueFromInitData (
    string key)
{
    return this.InitDatas.Single (x => x.Key == key).Value;
}

public string GetValueFromInitData (
    Enum key)
{
    return GetValueFromInitData (key.ToString ());
}

public T GetValueFromInitData (
    Enum key)
    where T : struct, IConvertible
{
    Type type = typeof (T);
    if (type.IsEnum)

    {
        return (T) Enum.Parse (typeof (T), GetValueFromInitData (key));
    }

    throw new NotImplementedException ("Unsupported type");
 }
I could then rewrite the original code like this:
if (commandEntity.HasInitData (InitDataKeys.MoiBliscyUpgradeType))
{
    this.UpgradeType = commandEntity.GetValueFromInitData (InitDataKeys.MoiBliscyUpgradeType);
}
 
It may not seem like a big difference, but well designed software is achieved though hundreds of little decisions that all add up.

Tuesday, July 12, 2011

How to Make Selenium Wait for Ajax Calls

I needed to be able to wait for Selenium to complete an Ajax call before checking the effects.  After looking at many different solutions, I came up with this one.

Add a hidden field to the master page to store the number of Ajax requests that have been done.
<input type="hidden" id="NumAjaxRequests" value="0" />
Hook into the jQuery Ajax framework to automatically increment the field for each request that completes.
$('.ajaxindicator').ajaxStop(function ()
{
    $('#NumAjaxRequests').val(parseInt($('#NumAjaxRequests').val() + 1));
});
You can then reset the field before performing the action that causes the Ajax call, perform that action and tell Selenium to wait until the expected number of Ajax calls have taken place.
| type         | NumAjaxRequests | 0                 |
| select       | Mb_SpouseId     | label=Spouse Name |
| waitForValue | NumAjaxRequests | 1                 |

Monday, July 11, 2011

Master Pages Refactored

The master pages have been refactored.  There are now two levels of master pages.

Page.Master is the top level master page that contains most of the structure, script, links, etc.

MvcSite-NoSummary.Master, MvcSite-WideSummary.Master and MvcSite.Master inherit from Page.Master and do the following:

1. Reference different style sheets
2. Repeat content place holders that the actual pages need from Page.Master
3. Add layout structure for the right panel if needed

Friday, July 8, 2011

Removing Duplicate Transaction Management Code

There is a method called WrapInTransaction on RemotingObjectBase that you should use to add transaction management to code in the remoting facade.

Instead of writing

public void RaiseBirthdayEvents ()
{
    StartTransaction (IsolationLevel.ReadCommitted, "RaiseBirthdayEvents");
    bool committed = false;    

    try
    {
        List<int> personIds = Accessors.PersonDA.FetchPersonIdsByBirthDt (Services.DateService.Today.Month, Services.DateService.Today.Day);            
        foreach (int personId in personIds)
        {
            Services.EventingService.RaiseEvent (EventType.Birthdate, Services.DateService.Today, Table.Person, personId);
        }        

        CommitTransaction ();
        committed = true;
    }
    finally
    {
        if (!committed)
        {
            RollbackTransaction ();
        }
    }
}

you can now write
public void RaiseBirthdayEvents ()
{
    WrapInTransaction ("RaiseBirthdayEvents", () => 
    {
        List<int> personIds = Accessors.PersonDA.FetchPersonIdsByBirthDt (Services.DateService.Today.Month, Services.DateService.Today.Day);

        foreach (int personId in personIds)
        {
            Services.EventingService.RaiseEvent (EventType.Birthdate, Services.DateService.Today, Table.Person, personId);
        }
    });
}

Similarly if the code being wrapped needs to return a value, then
public int CreateProlinkManualApplication ()
{
    bool committed = false;
    StartTransaction (IsolationLevel.ReadCommitted, "CreateApplication");

    try
    {
        ApplicationEntity application = ApplicationEntity.Create ();
        application.SaleSourceId = (int) SaleSource.ProsperityApplicationForm;
        Adapter.SaveEntity (application);

        CommitTransaction ();
        committed = true;

        return application.ApplicationId;
    }
    finally
    {
        if (!committed)
        {
            RollbackTransaction ();
        }
    }
}
becomes
public int CreateProlinkManualApplication ()
{
    return WrapInTransaction ("CreateApplication", () =>
    {
        ApplicationEntity application = ApplicationEntity.Create ();
        application.SaleSourceId = (int) SaleSource.ProsperityApplicationForm;
        Adapter.SaveEntity (application);                                               

        return application.ApplicationId;
    });
}
Finally here is the code for the two overloads of the wrapping method:
protected void WrapInTransaction (
    string transactionName,
    Action action)
{
    StartTransaction (IsolationLevel.ReadCommitted, transactionName);
    bool committed = false;

    try
    {
        action.Invoke ();

        CommitTransaction ();
        committed = true;
    }
    finally
    {
        if (!committed)
        {
            RollbackTransaction ();
        }
    }
}

protected T WrapInTransaction <T> (
    string transactionName,
    Func<T> function)
{
    StartTransaction (IsolationLevel.ReadCommitted, transactionName);
    bool committed = false;

    try
    {
        T result = function.Invoke ();

        CommitTransaction ();
        committed = true;

        return result;
    }
    finally
    {
        if (!committed)
        {
            RollbackTransaction ();
        }
    }
}

Thursday, July 7, 2011

Mocking LlblGen RetrievalProcedures

If you need to create a mock for one of the LlblGen classes such as RetrievalProcedures, you are faced with the problem that there is no interface for you to use.  Fortunately most of the classes generated by LlblGen are partials so you can use add your own code to them.

Suppose you need to mock out RetrievalProcedures and that it has a method called GetPins you want to mock:

public partial class RetrievalProcedures
{
    public virtual DataTable GetPins(System.Int32 numberOfPins)
    {
        using(DataAccessAdapter dataAccessProvider = new DataAccessAdapter())
        {
            return GetPins(numberOfPins, dataAccessProvider);
        }
    }

    public virtual DataTable GetPins(System.Int32 numberOfPins, IDataAccessCore dataAccessProvider)
    {
        using(StoredProcedureCall call = CreateGetPinsCall(dataAccessProvider, numberOfPins))
        {
            DataTable toReturn = call.FillDataTable();            
            return toReturn;
        }
    }

    ...
}

You can create a partial class next to it as well as the interface you need and let the partial class implement the interface:

public interface IRetrievalProcedures
{
    DataTable GetPins(System.Int32 numberOfPins);

    DataTable GetPins(System.Int32 numberOfPins, IDataAccessCore dataAccessProvider);
}

partial class RetrievalProcedures : IRetrievalProcedures
{
}

The original class now implements the new interface and you can go forth and mock.

Enums: The Dark Side

In a previous post I advocated using enums as much as possible.  There are however times when this is not a good idea.

If a lookup table requires the ability to easily add new lookup values without redeploying the code base, you should avoid using enums in data accessors, view models, etc. 

The situation we had involved document types. After adding a new document type, the code had to be updated.  This shouldn't be necessary in this case and should have just worked.

So as with most things, use common sense.  I suggest keeping a list of lookups that should not be dealt with using enums for your project.

Unit Testing Private Methods

Sometimes you want to write a unit test against a private method. 

First let me say that most of the time this is an indication of a design problem.  Rather consider whether your class really wants to be more than one class or whether you should be testing the code indirectly using one of the other public methods of the class.

If you are convinced you really want to write a unit test for the private method, there is an alternative to calling the method using AsDynamic ().  The problem with AsDynamic () is that you lose all the benefits of strong typing, including support for refactoring.

Lets say you have a class called Class1 like this:

public class Class1
{
    private void Method1 ()
    {
    }
}

In order to call Method1 you can change Method1 in Class1 to protected and create a testing subclass like this:

public class TestClass1
    : Class1
{
    public void TestMethod1 ()
    {
        Method1 ();
    }
}

In your tests you can then create an instance of TestClass1 and call TestMethod1.

Wednesday, July 6, 2011

Configuring Moq to return different results

If you need to create a mock that can return one result the first time and another the second time, you can use the MoqExtensions class like this:

MockPremiumCalculationService = new Mock<IPremiumCalculationService> ();
PremiumCalculationResponse response1 = new PremiumCalculationResponse ();
response1.Premium = 55;
PremiumCalculationResponse response2 = new PremiumCalculationResponse ();
response2.Premium = 60;
MockPremiumCalculationService.Setup (
    pcs => pcs.Calculate (It.IsAny<PremiumCalculationRequest> ()))
    .ReturnsInOrder (response1, response2);

For more info see this article by Phil Haack:

http://haacked.com/archive/2009/09/29/moq-sequences.aspx

Tuesday, July 5, 2011

Data Access from LD.FunctionalTest

Instead of writing a separate query for each entity in your test class e.g.
       
private List<PremiumEntity> FetchPremiums(
    params int[] policyIds)
{
    LinqMetaData metaData = new LinqMetaData(Adapter);
    var query = (from p in metaData.Premium
        where policyIds.Contains (p.PolicyId)
        select p);
    return query.ToList();
}

there is now a method on LinqMetadata you can use along with a property called MetaData on the TestBase class.The above code can now be replaced by a call inside your test that looks like this:

List<PremiumEntity> partnerPremiums = MetaData.GetEntities<PremiumEntity> ();

Similarly you can get the number of entities in the database by calling

List<PremiumEntity> partnerPremiums = MetaData.GetNumEntities<PremiumEntity> ();

Note that you don't need to get the number of entities in the database at the start and compare them with the number at the end because we always start with a clean database.

Friday, July 1, 2011

Use of enums

Try to use enums as much as possible.

For example, instead of writing

public DocumentEntity CreateDocument (
    int documentTypeId)
{
    DocumentEntity document = new DocumentEntity ();
    document.DocumentTypeId = documentTypeId;
    return document;
}

use

public DocumentEntity CreateDocument (
    DocumentType documentType)
{
    DocumentEntity document = new DocumentEntity ();
    document.DocumentTypeId = (int)documentType;
    return document;
}

This holds for data accessors, remoting objects, etc.