How do I Mock MongoDB Data Access Layer using Repository Pattern? - c#

I want to Test the Method FindAsync(Expression<Func>) from the MongoDB C# Driver. My goal is it to
test my expression, I don't want to Mock the FindAsync Method itself. In EF I would Mock the DB Set and return my own Enumerator which is filled with my IEnumerable with test data. Can I do something like that in MongoDB also?
I using the Driver Version 2.10.4
And the Framework Moq 4.14.5

The problem you have here is FindAsync(Expression<Func>) is an extention method that just creates a new ExpressionFilterDefinition with your expression and passes it on.
Expression<Func<TDocument, bool>> filter = // some expression.
collection.FindAsync(new ExpressionFilterDefinition<TDocument>(filter), options, cancellationToken);
So you'll need to mock out the following method on IMongoCollection<TDocument>
public override Task<IAsyncCursor<TProjection>> FindAsync<TProjection>(
FilterDefinition<TDocument> filter,
FindOptions<TDocument, TProjection> options,
CancellationToken cancellationToken = default (CancellationToken));
Here's a quick example using Moq
var list = new List<Class>
{
new Class {Id = "1", Name = "Name1"},
new Class {Id = "2", Name = "Name2"},
new Class {Id = "3", Name = "Name3"}
};
var collection = new Mock<IMongoCollection<Class>>();
collection.Setup(x => x.FindAsync<Class>(
It.IsAny<FilterDefinition<Class>>(),
It.IsAny<FindOptions<Class, Class>>(),
It.IsAny<CancellationToken>()
)).ReturnsAsync((FilterDefinition<Class> filter,
FindOptions<Class, Class> options,
CancellationToken cancellationToken) =>
{
// We'll need to get back the expression
var expressionFilter = (ExpressionFilterDefinition<Class>)filter;
// Filtered our mocked list
var filtererList = list.Where(expressionFilter.Expression.Compile())
.ToList();
// Return a stubbed cursor with our filtered list
return new StubAsyncCursor<Class>(filtererList) as IAsyncCursor<Class>;
});
var cursor = await collection.Object.FindAsync(x => x.Id == "2");
var result = await cursor.ToListAsync();
foreach (var item in result)
{
Console.WriteLine($#"Id: {item.Id}, Name: {item.Name}");
}
// Output
// Id: 2, Name: Name2
public class StubAsyncCursor<T> : IAsyncCursor<T>
{
private bool _disposed;
private bool _moved;
private readonly ICollection<T> _current;
public StubAsyncCursor(ICollection<T> current)
{
this._current = current;
}
public IEnumerable<T> Current
{
get
{
this.ThrowIfDisposed();
if (!this._moved)
throw new InvalidOperationException("Must call MoveNextAsync first");
return this._current;
}
}
public bool MoveNext(CancellationToken cancellationToken)
{
this.ThrowIfDisposed();
if (this._moved)
return false;
this._moved = true;
return true;
}
public Task<bool> MoveNextAsync(CancellationToken cancellationToken)
{
this.ThrowIfDisposed();
return Task.FromResult<bool>(this.MoveNext(cancellationToken));
}
public void Dispose()
{
this._disposed = true;
}
private void ThrowIfDisposed()
{
if (this._disposed)
throw new ObjectDisposedException(this.GetType().Name);
}
}
public class Class
{
public string Id { get; set; }
public string Name { get; set; }
}
Even though this is possible, this will only work when using an expression filter definition, I'd personally recommend just spinning up a local MongoDB instance, It's fast, simple and will prove all your queries work as they do in production.
docker run -d -p 27017:27107

Related

Moq for Interface that Inherits from ICollection returns null

I am trying to run unit tests using Moq. I am fairly new to Moq and I have ran into a problem with this current unit test.
I have a controller that is fetching some items. The result is encapsulated within a generic interface using ICollection.
public interface IResult
{
}
public interface IListResult : ICollection<IResult>
{
}
My controller is simply calling a method that returns the result.
[HttpGet("get/{userId}/{pageSize}/{fetchNext}")]
public IActionResult GetConversations(int userId, int pageSize, bool fetchNext)
{
try
{
GetConversationsByUserIdQuery query = new GetConversationsByUserIdQuery()
{
UserId = userId,
PageSize = pageSize,
FetchNext = fetchNext
};
var result = _mediator.GetConversationsByUserId(query);
return Ok(result);
}
catch (Exception ex)
{
return StatusCode(StatusCodes.Status500InternalServerError, ex.Message);
}
}
}
When I am running my unit test, the result always comes back null and I am failing to understand what I am missing in my set up.
[Theory]
[InlineData(1, 2 , false)]
[InlineData(1, 2 , true)]
public async void When_AddMessageToNewConversation_ThenSuccessfullyAdd(int userId, int pageSize, bool fetchNext)
{
// Arrange
Mock<IMessageMediator> _mediator = new Mock<IMessageMediator>();
Mock<IListResult> _listResult = new Mock<IListResult>();
GetConversationsByUserIdQuery query = new GetConversationsByUserIdQuery()
{
UserId = userId,
PageSize = pageSize,
FetchNext = fetchNext
};
List<Conversation> expected = new List<Conversation>()
{
new Conversation()
{
Id = Guid.NewGuid(),
Created_At = DateTimeOffset.Now
}
};
_listResult.Setup(x =>
x.GetEnumerator())
.Returns(expected.GetEnumerator());
GetConversationsByUserIdController controller = new GetConversationsByUserIdController(_mediator.Object);
_mediator.Setup(x =>
x.GetConversationsByUserId(query)).Returns(_listResult.Object);
// Act
IActionResult result = controller.GetConversations(userId, pageSize, fetchNext);
// Assert
Assert.True(result is OkResult);
}
The IMessageMediator is simply a delegator that handles implementation of queriers and commands. The IListResult is returned from a querier handler.
public class GetConversationsByUserIdQueryHandler:
IQueryHandler<GetConversationsByUserIdQuery>
{
private IRepository<Conversations_By_UserId>
_conversationByUserIdRepository;
private IListResult _result;
public GetConversationsByUserIdQueryHandler(IRepository<Conversations_By_UserId> conversationByUserIdRepository,
IListResult result)
{
_conversationByUserIdRepository = conversationByUserIdRepository;
_result = result;
}
public IListResult Handle(GetConversationsByUserIdQuery query)
{
IEnumerable<Conversations_By_UserId> conversations = _conversationByUserIdRepository
.Get(query.PageSize,
query.FetchNext,
message => message.UserId == query.UserId).ToList();
if (conversations.Any())
{
foreach (Conversations_By_UserId m in conversations)
{
_result.Add(new Conversation()
{
Created_At = m.Created_At,
Id = m.Id,
});
}
}
return _result;
}
}
You don't need to mock both IMessageMediator and IListResult.
You should mock dependencies - it is IMessageMediator in your case - and your can setup it to return any result.
The other thing - you mock _mediator using query created in test, but in controller you create different query (references are different) and it is the reason of null result.
Change your test:
[Theory]
[InlineData(1, 2 , false)]
[InlineData(1, 2 , true)]
public async void When_AddMessageToNewConversation_ThenSuccessfullyAdd(int userId, int pageSize, bool fetchNext)
{
// Arrange
Mock<IMessageMediator> _mediator = new Mock<IMessageMediator>();
List<Conversation> expected = new List<Conversation>()
{
new Conversation()
{
Id = Guid.NewGuid(),
Created_At = DateTimeOffset.Now
}
};
GetConversationsByUserIdController controller = new GetConversationsByUserIdController(_mediator.Object);
// It.IsAny<GetConversationsByUserIdQuery>()) instead of query
_mediator.Setup(x => x.GetConversationsByUserId(It.IsAny<GetConversationsByUserIdQuery>()))
// create fake result to return from mediator (no need to mock IListResult
.Returns(new ListResult() ...); // just create instance of IListResult with needed values
// Act
IActionResult result = controller.GetConversations(userId, pageSize, fetchNext);
// Assert
Assert.True(result is OkResult);
}

Why do I get System.ArgumentException in my xunit test result?

Here is the method I want to write test for:
public class JobStore : IJobStore
{
private readonly IMongoDbContext _context;
public JobStore(IMongoDbContext context)
{
_context = context;
}
public async Task<IJob> CreateAsync(IJob job)
{
await _context.Jobs.InsertOneAsync(job as Job);
return job;
}
}
Here is my test :
public class JobStoreTest
{
private readonly Mock<IMongoDbContext> _moqIMongoDbContext;
private readonly JobStore _jobStore;
public JobStoreTest()
{
_moqIMongoDbContext = new Mock<IMongoDbContext>();
_jobStore = new JobStore(_moqIMongoDbContext.Object);
_moqIMongoDbContext
.Setup(_ => _.Jobs.InsertOneAsync(It.IsAny<Job>(), It.IsAny<CancellationToken>()))
.Returns((IJob x) => Task.FromResult(x));
}
[Theory]
[ClassData(typeof(JobClassesForTesting))]
public async Task CreateAsync(IJob job)
{
var result = await _jobStore.CreateAsync(job);
Assert.Equal(job,result as Job);
}
}
Here is the result of test:
System.ArgumentException
Invalid callback. Setup on method with 2 parameter(s) cannot invoke callback with different number of parameters (1).
Here is the JobClassesForTestingClass which is my scenario for testing :
public class JobClassesForTesting : IEnumerable<object[]>
{
public IEnumerator<object[]> GetEnumerator()
{
yield return new object[]
{
new Job()
{
Payload = null,
EntityName = "EntityNameTest1",
Module = "ModuleTest1",
MetaData = new Dictionary<string, string>(),
Categories = new List<JobCategory>{new JobCategory {Name = "CategoryTest1"} },
PublishedDate = DateTime.Now
}
};
yield return new object[]
{
new Job()
{
Payload = "PayloadTest2",
EntityName = "EntityNameTest2",
Module = "ModuleTest2",
MetaData = new Dictionary<string, string>(),
Categories = new List<JobCategory>{new JobCategory {Name = "CategoryTest2"} },
PublishedDate = DateTime.Now
}
};
yield return new object[]
{
new Job()
{
Payload = "PayloadTest3",
EntityName = "EntityNameTest3",
Module = "ModuleTest3",
MetaData = new Dictionary<string, string>(),
Categories = new List<JobCategory>{new JobCategory {Name = "CategoryTest3"} },
PublishedDate = DateTime.Now
}
};
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
I want the result of the test would be as same as each of my Job objects but the result of the test is System.ArgumentException
The exception clearly states the problem about the arguments count mismatch.
Refactor the mock setup
_moqIMongoDbContext
.Setup(_ => _.Jobs.InsertOneAsync(
It.IsAny<Job>(),
It.IsAny<InsertOneOptions>(),
It.IsAny<CancellationToken>())
)
.Returns((Job document, InsertOneOptions options, CancellationToken token)
=> Task.FromResult(document));
Note how the parameters in the Returns delegate/callback now matches the number and types of argument matchers used by the member that was setup.
IMongoCollection.InsertOneAsync Method (TDocument, InsertOneOptions, CancellationToken)
Task InsertOneAsync(
TDocument document,
InsertOneOptions options = null,
CancellationToken cancellationToken = null
)
Reference Moq Quickstart to get a better understanding of how to use that mocking library

Mock custom implementation of CodeAccessSecurityAttribute

I have a custom implementation of CodeAccessSecurityAttribute that is connecting external sources to do a validation.
[Serializable]
[AttributeUsage(AttributeTargets.Method)]
public class IsAuthorizedAttribute : CodeAccessSecurityAttribute
{
private static readonly PrincipalPermission Allowed = new PrincipalPermission(PermissionState.None);
private static readonly PrincipalPermission NotAllowed = new PrincipalPermission(PermissionState.Unrestricted);
public string EntityObject { get; set; }
public string Field { get; set; }
public char Expected { get; set; }
public IsAuthorizedAttribute(SecurityAction action)
: base(action)
{
//setup
}
public override IPermission CreatePermission()
{
return IsAuthorised(EntityObject, Field, Expected, ServicesConfiguration) ? Allowed : NotAllowed;
}
private static bool IsAuthorised(string entityObject, string field, char expected, ServicesConfiguration servicesConfiguration)
{
bool? response = null;
//check external stuff
return response ?? false;
}
}
I have decorated my methods with this attribute:
[IsAuthorized(SecurityAction.Demand, EntityObject = Fields.UserManagement, Field = Fields.AllowDisplay, Expected = '1')]
public List<Group> GetUserGroups()
{
var response = new List<Group>();
//Get the groups from the database
var groups = groupManager.FindAll();
//Map them to the output group type
response = groups.Select(x => new Group()
{
ID = x.ID,
Name = x.Name,
Alias = x.Alias,
Description = x.Description
}).ToList();
return response;
}
I now want to unit test this method, but the attribute is fired. I have tried some things to mock the attribute, but without success.
I'm using Moq and Smocks.
This is my unit test without a mocked instance of the attribute:
[TestMethod]
public void GetUserGroups_UserGroupsFound_UserGroupsReturned()
{
Smock.Run(context =>
{
//Arrange
Setup();
m_Container
.RegisterMock<IGroupManager>()
.Setup(x => x.FindAllFromCache())
.Returns(new List<Concept.Security.MasterData.Domain.Group>()
{
new Concept.Security.MasterData.Domain.Group()
{
Name = "MyUserGroup",
Alias = "My User Group",
Description = "My user group description",
System = false,
Authorizations = "000001111100000000"
},
new Concept.Security.MasterData.Domain.Group()
{
Name = "MySecondUserGroup",
Alias = "My Second User Group",
Description = "My second user group description",
System = false,
Authorizations = "000000000000000000"
}
});
var identityService = new UserManagementService(m_Container, m_UserAuthorizationManager.Object, m_IdentityService.Object);
//** begin add mocked attribute **//
//** end add mocked attribute **//
//Act
var response = identityService.GetUserGroups();
//Assert
Assert.AreEqual(2, response.Count);
Assert.AreEqual(1, response.Where(x => x.Alias == "MyUserGroup").Count());
Assert.AreEqual(1, response.Where(x => x.Alias == "MySecondUserGroup").Count());
Assert.AreEqual(2, response.Where(x => x.Authorizations == null).Count());
});
}
Running this results in an exception because the attribute tries to connect the external services and they aren't (and can't be) setup to receive requests.
So, I try to add a mocked attribute:
//** begin add mocked attribute **//
var identityService = new UserManagementService(m_Container, m_UserAuthorizationManager.Object, m_IdentityService.Object);
var IsAuthorizedAttribute = new Mock<IsAuthorizedAttribute>(MockBehavior.Strict, new object[] { SecurityAction.Demand });
IsAuthorizedAttribute.Setup(x => x.CreatePermission()).Returns(new PrincipalPermission(PermissionState.None));
TypeDescriptor.AddAttributes(identityService, IsAuthorizedAttribute.Object);
//** end add mocked attribute **//
But this one is calling the constructor of the attribute where I set up the external source. When I put this constructor in a try/catch and silently disposing the exception, I have an error on IsAuthorizedAttribute.Object object can't be found.
What are other options to not fire the attribute?
Constructors should not access externals; otherwise it will be difficult to bypass for testing, as you know.
A simple way is to make static bool field to bypass. This does not look so good but maybe enough.
public class IsAuthorizedAttribute : CodeAccessSecurityAttribute
{
// set true in the test initialization
private static bool s_byPass;
public IsAuthorizedAttribute(SecurityAction action) : base(action)
{
if (!s_byPass)
{
// setup
}
}
private static bool IsAuthorised(string entityObject, string field, char expected, ServicesConfiguration servicesConfiguration)
{
if (s_byPass) { return true; }
//check external stuff
}
}
Another better approach is to extract the external dependency to another class so that you can mock it. Mocking external dependencies is a typical pattern of a unit test.
public class IsAuthorizedAttribute : CodeAccessSecurityAttribute
{
// set mock here in the test initialization.
// I assume external accessor can be a static field.
private static ExternalAccessor m_accessor = new ExternalAccessor();
private static bool IsAuthorised(string entityObject, string field, char expected, ServicesConfiguration servicesConfiguration)
{
return m_accessor.Check();
}
}
public class ExternalAccessor
{
private bool m_initialized;
private void Setup()
{
// setup
m_initialized = true;
}
public virtual bool Check()
{
// You can call setup anytime but the constructor.
if (!m_initialized) { Setup(); }
// check external stuff
}
}

How to Unit Test without Hitting Database

I want to ask what is a good unit test for the method below GetMeetingsByInterimIdentifier where interim identifier is a string -- such as 78th2015.
We are setup to use the interface IMeetingsService. We are using MOQ and Microsoft.VisualStudio.TestTools.UnitTesting.
public class MeetingsService : IMeetingsService
{
private readonly IInterimCommitteeDbContext _db;
public MeetingsService(IInterimCommitteeDbContext db)
{
this._db = db;
}
public IQueryable<Meeting> GetMeetingsByInterimIdentifier(string interimIdentifier)
{
return
from m in this._db.Meetings
join c in this._db.Committees on m.CommitteeId equals c.CommitteeId
where c.InterimIdentifier == interimIdentifier
select m;
}
public Meeting GetMeeting(int meetingKey)
{
return this._db.Meetings.FirstOrDefault(x => x.MeetingId == meetingKey);
}
}
Edit:
But I am not sure how to set it up. This result is not null, but what does it do for me?
[TestMethod]
public void GetMeetingsByInterimIdentifier_WithInterimIdentifier_ReturnsMeetingList()
{
//Arrange
var interim = Properties.Settings.Default.DefaultInterimIdentifier;
var result = _meetingServiceMock.Setup(x => x.GetMeetingsByInterimIdentifier(interim));
//Act
//Assert
Assert.IsNotNull(result);
}
Create a Mock<IInterimCommitteeDbContext> and pass it into the constructor. On this object setup the Meetings and Committees properties to return various collections.
You should have different tests setup that return different collections. For example, how should this behave if both the Meetings and Committees are empty, i.e. there is no data in the database? How should it behave if there isn't an object with the provided InterimIdentifier? What about if there is one that matches etc.
I figured out how to do this using test doubles. I am using Entity Framework 6 with the code first model. I created a DbContext that inherited from my I-DbContext interface. Then I was able to create in-memory data to use in my service layer unit tests. Below is an example of:
the test data context,
the test dbset,
an example unit test.
This solution was available from an msdn article here:
https://msdn.microsoft.com/en-us/data/dn314429.aspx
...
public class CommitteeContextTest : ICommitteeDbContext
{
public CommitteeContextTest()
{
this.Committees = new TestDbSet();
this.CommitteeMembers = new TestDbSet();
}
public Database Database { get; }
public DbSet Committees { get; set; }
public DbSet CommitteeMembers { get; set; }
}
}
public class TestDbSet : DbSet, IQueryable, IEnumerable, IDbAsyncEnumerable
where TEntity : class
{
ObservableCollection _data;
IQueryable _query;
public TestDbSet()
{
_data = new ObservableCollection();
_query = _data.AsQueryable();
}
public override TEntity Add(TEntity item)
{
_data.Add(item);
return item;
}
public override TEntity Remove(TEntity item)
{
_data.Remove(item);
return item;
}
public override TEntity Attach(TEntity item)
{
_data.Add(item);
return item;
}
public override TEntity Create()
{
return Activator.CreateInstance();
}
}
[TestClass]
public class CommitteeServiceTest
{
private InterimCommitteeContextTest _interimCommitteeContext;
private ICommitteeService _service;
private string _interim;
[TestInitialize]
public void SetUp()
{
_interimCommitteeContext = new InterimCommitteeContextTest();
_service = new CommitteeService(_interimCommitteeContext);
_interim = Settings.Default.DefaultInterimIdentifier;
}
[TestCleanup]
public void Teardown()
{
_interimCommitteeContext = null;
_service = null;
}
[TestMethod]
public void GetCommittee_ProvideInterimCommitteeId_ReturnOneCommittee()
{
//Arrange
AddCommittees();
//Act and Assert
var result = _service.GetCommittee(_interim, 1);
Assert.AreEqual(1, result.CommitteeId); //Passes. IsActive set to true;
result = _service.GetCommittee(_interim, 0);
Assert.IsNull(result); //Fails. No committeeId = 0;
result = _service.GetCommittee(_interim, 2);
Assert.IsNull(result); //Fails. CommitteeId = 2 is not active.
}
[TestMethod]
public void AddCommittees()
{
_interimCommitteeContext.Committees.Add(new Committee() { CommitteeId = 1, InterimIdentifier = _interim, IsActive = true, CommitteeTypeId = 1 });
_interimCommitteeContext.Committees.Add(new Committee() { CommitteeId = 2, InterimIdentifier = _interim, IsActive = false, CommitteeTypeId = 1 });
_interimCommitteeContext.Committees.Add(new Committee() { CommitteeId = 3, InterimIdentifier = _interim, IsActive = true, CommitteeTypeId = 1 });
}
}
Use Mocking, that's what it is for. Use JMock or Mockito or any other library you prefer.

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();
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
I know you specifically asked how to do this using Moq, and I don't have an answer to that, but I figured out how to do something similar using Fakes.
http://azurator.blogspot.com/2013/07/unit-testing-azure-table-storage-queries.html
Essentially you can create a Shim on CloudTableQuery<T> that reads the Expression object the query is using and applies that same logic to your IEnumerable using code like this:
[TestMethod]
public void here_is_my_test()
{
IEnumerable<MyEntityType> fakeResults = GetFakeResults();
using (ShimsContext.Create())
{
InterceptCloudTableQueryExecute<MyEntityType>(fakeResults);
DoQuery();
AssertStuff();
}
}
public void InterceptCloudTableQueryExecute<T>(IEnumerable<T> result)
{
var query = result.AsQueryable();
ShimCloudTableQuery<T>.AllInstances.Execute = (instance) =>
{
// Get the expression evaluator.
MethodCallExpression ex = (MethodCallExpression)instance.Expression;
// Depending on how I called CreateQuery, sometimes the objects
// I need are nested one level deep.
if (ex.Arguments[0] is MethodCallExpression)
{
ex = (MethodCallExpression)ex.Arguments[0];
}
UnaryExpression ue = ex.Arguments[1] as UnaryExpression;
// Get the lambda expression
Expression<Func<T, bool>> le = ue.Operand as Expression<Func<T, bool>>;
query = query.Where(le);
return query;
};
}

Categories

Resources