如何使用Moq使用存根单元测试Windows Azure表查询?

Fre*_*rej 7 c# unit-testing moq azure-table-storage

我无法使我的单元测试正常工作.它适用于我实际遇到Azure表存储的集成测试.我猜的问题是对属性QueryableEntities的模拟,它从mock中重新构造了一个Queryable,但它从ServiceContext类返回一个DataServiceQuery.是否可以创建一个返回Queryable的DataServiceQuery类型的存根?

这是我的代码:

测试

[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);
    }
Run Code Online (Sandbox Code Playgroud)

IServiceContect接口

public interface IServiceContext<TEntity>
{
    IQueryable<TEntity> QueryableEntities {get;}
}
Run Code Online (Sandbox Code Playgroud)

ServiceContext类

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);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

字典存储库

     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;

    }} 
Run Code Online (Sandbox Code Playgroud)

我收到以下错误

错误:

    ArgumentNullException was unhandeled by user code
    Value cannot be null.
    Parameter name: query
Run Code Online (Sandbox Code Playgroud)

我在DictionaryRepository类的以下行调用.AsTableServiceQuery()时收到错误:

var q = this.Context.QueryableEntities.Where(x => x.PartitionKey == Dictionary.ToString() && x.RowKey == word).AsTableServiceQuery();
Run Code Online (Sandbox Code Playgroud)

Ric*_*nks 1

您没有提到您遇到的错误,但由于 是QueryableEntities只读属性,请尝试使用mock.SetupGet而不是mock.Setup.

编辑:

进一步研究,问题在于.AsTableServiceQuery()扩展方法尝试将 强制转换IQueryable<T>为 a DataServiceQuery<T>,但失败导致 null 异常。

Frederic Boerr 发表了一篇关于如何使用表存储进行单元测试的文章,应该可以帮助您。Windows Azure 存储:TDD 和模拟