Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I unit test Windows Azure Table query with a stub using Moq?

I can't get my unit test to work properly.

It works in a integration test I have where it will actually hit the Azure Table Storage.

The problem I guess is the mocking of the property QueryableEntities which returns a Queryable<Word> from the mock but it returns a DataServiceQuery from the ServiceContext class. Is it possible to create a stub of type DataServiceQuery which returns a Queryable?

This is my code:

Test

[TestMethod]
    public void GetAExistingWordInStorageShouldReturnCorrectWord()
    {

        Word expected = new Word(Dictionaries.Swedish.ToString(), "Word", "Word");

        List<Word> Words = new List<Word>();
        Words.Add(new Word(Dictionaries.Swedish.ToString(), "Word", "Word"));

        IQueryable<Word> WordQueryable = Words.AsQueryable<Word>();
        
        var mock = new Mock<IServiceContext<Word>>();
        mock.Setup(x => x.QueryableEntities).Returns(WordQueryable);

        DictionaryRepository dr = new DictionaryRepository(Models.Dictionaries.Swedish, "testdictionaries");
        dr.Context = mock.Object;

        Word result = dr.GetWord(expected.Text, false);

        Assert.AreEqual(expected, result);
    }

IServiceContect interface

public interface IServiceContext<TEntity>
{
    IQueryable<TEntity> QueryableEntities {get;}
}

ServiceContext Class

public class ServiceContext<TEntity> : TableServiceContext, IServiceContext<TEntity> where TEntity : TableServiceEntity
{

    private readonly string tableName;

    public ServiceContext(CloudStorageAccount account, String tableName)
        : base(account.TableEndpoint.ToString(), account.Credentials)
    {
        this.tableName = tableName;
        this.IgnoreResourceNotFoundException = true;
    }

    public IQueryable<TEntity> QueryableEntities
    {
        get
        {
            return CreateQuery<TEntity>(tableName);
        }
    }

}

Dictionary Repository

     public class DictionaryRepository : IDictionaryRepository
{
    public Dictionaries Dictionary { get; set; }
    public String TableName;

    public IServiceContext<Word> Context;

    public DictionaryRepository(Dictionaries dictionary)
        : this(dictionary, "dictionaries")
    {
    }

    public DictionaryRepository(Dictionaries dictionary, String tableName)
    {
        Dictionary = dictionary;
        this.TableName = tableName;
        CloudStorageAccount account = CloudStorageAccount.Parse(***);
        Context = new ServiceContext<Word>(account, this.TableName);
    }

    public List<Tile> GetValidTiles()
    {
        throw new NotImplementedException();
    }

    public Type ResolveEntityType(String name)
    {
        return typeof(Word);
    }

    public Word GetWord(string word, Boolean useCache = false)
    {
      
        var q = this.Context.QueryableEntities.Where(x => x.PartitionKey == Dictionary.ToString() && x.RowKey == word).AsTableServiceQuery();

        Word result = q.Execute().SingleOrDefault();

        if (result == null)
            return null;

        return result;

    }} 

I'm getting the following error

Error:

    ArgumentNullException was unhandled by user code
    Value cannot be null.
    Parameter name: query

I get the error when calling .AsTableServiceQuery() on the following line in DictionaryRepository class:

var q = this.Context.QueryableEntities.Where(x => x.PartitionKey == Dictionary.ToString() && x.RowKey == word).AsTableServiceQuery();
like image 304
Frej Avatar asked Feb 05 '12 15:02

Frej


1 Answers

You haven't mentioned the error you're getting, but since the QueryableEntities is a readonly property try using mock.SetupGet instead of mock.Setup.

EDIT:

Looking into it further the problem is that the .AsTableServiceQuery() extension method attempts to cast the IQueryable<T> to a DataServiceQuery<T>, which fails causing the null exception.

There's a post by Frederic Boerr about how to do unit testing with table storage that should help you out. Windows Azure Storage: TDD and mocks

like image 183
Richard Banks Avatar answered Sep 28 '22 07:09

Richard Banks