问题
In my unit test I want to test my method that I created for filtering data from MongoDB.
When I try to mock my function like this:
_repo.GetFluent<Location>((Arg.Any<Expression<Func<Location, bool>>>()))
.Returns(x => locations.Where(x.Arg<Expression<Func<Location, bool>>>()).ToList());
It underlines the Returns
saying:
Cannot convert lambda expression.
Before when I worked on my simple project using the 2.0.0 MongoDB driver I had no problem mocking my Get()
function like this, but now with the new 2.2.3 driver I have an error mocking this. Is there another way?
I've seen that the new driver is using IFindFluent
and the older one I used the MongoCursor
to get my data.
Should I mock the IFindFluent
somehow?
This is my code for the GetFluent()
method
public IFindFluent<TEntity, TEntity> GetFluent<TEntity>(System.Linq.Expressions.Expression<Func<TEntity, bool>> filter = null) where TEntity : class, new()
{
var collection = GetCollection<TEntity>();
if (filter == null)
{
var emptyFilter = Builders<TEntity>.Filter.Empty;
return collection.Find(emptyFilter);
}
else
{
var filterDefinition = Builders<TEntity>.Filter.Where(filter);
return collection.Find(filterDefinition);
}
}
回答1:
Yes, you need to mock IFindFluent. Let me show you an example.
I used NUnit and Moq for tests, driver version is 2.2.3.
public interface IRepository
{
IFindFluent<TEntity, TEntity> GetFluent<TEntity>(Expression<Func<TEntity, bool>> filter = null)
where TEntity : class, new();
}
public class LocationService
{
public long CountLocations(IRepository repository)
{
return repository.GetFluent<Location>(location => true).Count();
}
}
[TestFixture]
public class LocationServiceTests
{
[Test]
public void CountLocationsTest()
{
const long LocationCount = 5;
var locationsMock = new Mock<IFindFluent<Location, Location>>();
locationsMock.Setup(x => x.Count(default(CancellationToken))).Returns(LocationCount);
var repoMock = new Mock<IRepository>();
repoMock.Setup(repo => repo.GetFluent(It.IsAny<Expression<Func<Location, bool>>>()))
.Returns(locationsMock.Object);
var locationService = new LocationService();
long result = locationService.CountLocations(repoMock.Object);
Assert.AreEqual(LocationCount, result);
}
}
回答2:
Good answer from Usein Mambediev. There is an similar example, how to mock IFindFluent with Typemock Isolator without wrapping it into the interface:
[TestMethod, Isolated]
public void TestGet()
{
var target = new ClassUnderTest();
var returnMock = Isolate.Fake.Instance<IFindFluent<Location, Location>>();
int size = 3;
Isolate.WhenCalled(() => returnMock.Count()).WillReturn(size);
Isolate.WhenCalled(() => target.GetFluent(default(Expression<Func<Location, bool>>))).WillReturn(returnMock);
Assert.AreEqual(size, target.GetFluent<Location>(location => true).Count());
}
I've put your method into the public class just in order to test. You only need to change the target. Good luck!
来源:https://stackoverflow.com/questions/35895872/cant-mock-my-get-function-from-my-repository-mongodb-driver-2-2-3