I have been getting a null reference error when running my test but cant figure it out. Below is my test
[Test]
[TestCase(...)]
public void Get_ShouldReturnTradesMock(string field, Operator op, int dayManip, SortDirection sortDir, string filterTerm, int pageIndex, int pageSize, int expectedRecordMinSize)
{
using (var _imprintDbContext = new ImprintDbContext(_dbContextOptions))
{
var mockExecRepo = new Mock<IExecutionReportRepository>();
mockExecRepo.Setup(mock => mock.GetFilteredTrades(It.IsAny<IEnumerable<Query>>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>())).Verifiable();//.Returns<Task<PagedResult<ExecutionReport>>>(x => null);
var uow = new Mock<IUnitOfWork>();
uow.SetupGet(x => x.ExecutionReports).Returns(mockExecRepo.Object);
var controller = new TradesController(uow.Object);
var query = new Query()
{
Field = field,
Operator = op,
Search = DateTime.Now.Add(TimeSpan.FromDays(dayManip)).Date.ToString("yyyy-MM-dd"),
SortDirection = sortDir
};
TradesController.TradesBody tb = new TradesController.TradesBody()
{
queries = new[] { query },
filterTerm = filterTerm
};
var results = controller.Get(tb, pageIndex, pageSize);
uow.Verify(mock => mock.ExecutionReports.GetFilteredTrades(new[] { query }, pageIndex, pageSize, filterTerm), Times.Once());
}
}
And the definitions of some of the objects I am mocking:
public interface IExecutionReportRepository : IRepository<ExecutionReport>
{
...
Task<IPagedResult<ExecutionReport>> GetFilteredTrades(IEnumerable<Query> queries, int pageIndex, int pageSize, string filterTerm);
}
UnitOfWork:
public class UnitOfWork : IUnitOfWork
{
private readonly DbContext _context;
public UnitOfWork(DbContext context, IExecutionReportRepository executionReportRepository)
{
_context = context;
ExecutionReports = executionReportRepository;
}
public IExecutionReportRepository ExecutionReports { get; }
}
TradesController:
public class TradesController : Controller
{
public class TradesBody
{
public IEnumerable<Query> queries;
public string filterTerm;
}
private readonly IUnitOfWork unitOfWork;
public TradesController(IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;
}
/// <summary>
/// Gets a list of trades for the current date
/// </summary>
[HttpPost]
public async Task<IActionResult> Get([FromBody] TradesBody postBody, int pageIndex = 0, int pageSize = 100)
{
string filterTerm = postBody.filterTerm ?? "";
IEnumerable<Query> queries = postBody.queries;
IPagedResult<Domain.Entities.Core.ExecutionReport> queryResult;
queryResult = await unitOfWork.ExecutionReports.GetFilteredTrades(queries, pageIndex, pageSize, filterTerm); //Null reference error here
return Ok(queryResult);
}
}
When stepping through the code, I do not see any null objects and thus cannot actually see/understand where the null reference is actually being found, however I have noticed that I cannot see the method definition during debug time for 'GetFilteredTrades. Judging by this, my mocked method is not connecting to the method being executed, however I only have one GetFilteredTrades.
How do I resolve the null reference error being thrown in the TradesController and successfully run my test?
You are not setting up GetFilteredTrades to return anything so it is failing when you try to await it.
mockExecRepo
.Setup(mock => mock.GetFilteredTrades(It.IsAny<IEnumerable<Query>>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>()))
.ReturnAsync(Mock.Of<IPagedResult<ExecutionReport>>()) //<--THIS
.Verifiable();
Also the method under test is async, so the test should be async as well.
[Test]
[TestCase(...)]
public async Task Get_ShouldReturnTradesMock(string field, Operator op, int dayManip, SortDirection sortDir, string filterTerm, int pageIndex, int pageSize, int expectedRecordMinSize)
{
and the method under test call awaited
var results = await controller.Get(tb, pageIndex, pageSize);
Finally, you are verifying the wrong mock based on the setup. Since the mockExecRepo setup has Verifiable() then you can simply call Verify() on the mock.
//...
//Act
var results = await controller.Get(tb, pageIndex, pageSize);
//Assert
mockExecRepo.Verify();
to verify that it was invoked as expected.
Related
I am using .NET Core and SQLKata to access SQL Server database.
I have a method to get all records from the database using SQLKata.Execution.PaginationResult.
This is in Repository:
public class MyTableRepository : IMyTableRepository
{
private QueryFactory _db;
public MyTableRepository(IConfiguration configuration)
{
var conn = new
SqlConnection(configuration.GetConnectionString("MyTable"));
_db = new QueryFactory(conn, new SqlKata.Compilers.SqlServerCompiler());
}
public PaginationResult<MyModel> GetAll(int page = 0, int perPage = 25)
{
dbResult = _db.Query("MyTable").Paginate<MyModel>(page, perPage);
return dbResult;
}
The above is called from my Controller like so:
private readonly IMyTableRepository _MyTableRepository;
public MyTableController(IMyTableRepository MyTableRepository)
{
_MyTableRepository = MyTableRepository;
}
[HttpGet]
[Route("GetMyTable")]
public List<MyModel> GetMyTable()
{
PaginationResult<MyModel> dbResult = MyTableRepository.GetAll(1,
25);
List<MyModel> AccumResult = dbResult.List.ToList();
while(dbResult.HasNext)
{
dbResult = dbResult.Next();
AccumResult.AddRange(dbResult.List.ToList());
}
return AccumResult;
}
How do I get the Next set of result from dbResult ?
I tried below, after I execute GetMyTable, I execute GetNextMyTable, but in PaginationResult GetNext(), dbResult is always null.
In controller:
[HttpGet]
[Route("GetNextMyTable")]
public List<MyTable> GetNextMyTable()
{
var result = _MyTableRepository.GetNext().List;
return result.ToList();
}
In Repository:
public PaginationResult<MyTable> GetNext()
{
while(dbResult.HasNext) //--->> dbResult is null
{
dbResult = dbResult.Next();
return dbResult;
}
return null;
}
If I do the Next method inside the Controller, I am also getting an error
private readonly IMyTableRepository _MyTableRepository;
private PaginationResult<SP_SMA_Reporting_Accts> dbResult;
[HttpGet]
[Route("GetMyTable")]
public List<MyModel> GetMyTable()
{
var dbResult = _MyTableRepository.GetAll(1, 25).List;
return dbResult.ToList();
}
[HttpGet]
[Route("GetNextMyTable")]
public List<MyTable> GetNextMyTable()
{
var result = dbResult.Next().List;//->Error since dbResult is null
return result.ToList();
}
In short refactor your repository method GetAll to call the db.Query
use:
_db.Query("MyTable").Paginate<MyModel>(page, perPage);
instead of
_db.Paginate<MyModel>(new Query("MyTable"), page, perPage);
Explanation:
when calling the Next() method the PaginationResult delegate the pagination process to the holding query, in your case since your are passing new Query() thus no connection info, you are getting null.
I am really new to XUnit and I will appreciate some help.
Controller
I have a really simple API method that adds a bug comment
[HttpPost("{bugId}/comment")]
public async Task<IActionResult> AddComment(Guid bugId, [FromBody] AddCommentForm form)
{
return await _bugService.AddComment(bugId, form) switch
{
Option<BugViewModel>.Some(var bug) => Ok(bug),
Option<BugViewModel>.None => NotFound(),
_ => throw new InvalidOperationException()
};
}
Service
The BugService method AddComment looks like this
public async Task<Option<BugViewModel>> AddComment(Guid bugId, AddCommentForm form)
{
if (await DbBugs.SingleOrDefaultAsync(x => x.Id == bugId) is { } bug)
{
var bugComment = new BugComment
{
Text = form.Text,
Commenter = form.Commenter,
CommentedAt = DateTime.Now,
Bug = bug
};
await _dbContext.BugComments.AddAsync(bugComment);
await _dbContext.SaveChangesAsync();
return new Option<BugViewModel>.Some(BugViewModel.FromData(bug));
}
return new Option<BugViewModel>.None();
}
ViewModels
I am adding the implementation of BugViewModel and BugCommentViewModel with their static FromData methods
public class BugViewModel
{
public Guid Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public List<BugCommentViewModel> Comments { get; set; }
public static BugViewModel FromData(Bug bug)
{
return new BugViewModel
{
Id = bug.Id,
Title = bug.Title,
Description = bug.Description,
Comments = bug.Comments.Select(BugCommentViewModel.FromData).ToList()
};
}
}
public class BugCommentViewModel
{
public Guid Id { get; set; }
public string Text { get; set; }
public string Commenter { get; set; }
public DateTime CommentedAt { get; set; }
public static BugCommentViewModel FromData(BugComment comment)
{
return new BugCommentViewModel
{
Id = comment.Id,
Text = comment.Text,
Commenter = comment.Commenter,
CommentedAt = comment.CommentedAt.ToLocalTime()
};
}
}
Testing
The Unit Tests look like this
public class BugContollerTests
{
private class Fixture
{
public IBugService BugService { get; } = Substitute.For<IBugService>();
public BugController GetSut() => new BugController(BugService);
}
private readonly Fixture _fixture = new Fixture();
[Fact]
public async Task Create_ResponseBodyIsCreatedBug()
{
var bug = BugViewModel.FromData(FakeBug.I.Generate());
_fixture.BugService.Create(Arg.Any<CreateBugForm>()).Returns(bug);
var sut = _fixture.GetSut();
var response = Assert.IsAssignableFrom<CreatedAtActionResult>(await sut.Create(new CreateBugForm()));
Assert.Same(bug, response.Value);
}
[Fact]
public async Task AddComment_CommentIsAddedtoViewModel()
{
_fixture.BugService.AddComment(Arg.Any<Guid>(), Arg.Any<AddCommentForm>()).Returns(new Option<BugViewModel>.Some(new BugViewModel()));
var sut = _fixture.GetSut();
var response = Assert.IsAssignableFrom<ObjectResult>(await sut.AddComment(Guid.Empty,new AddCommentForm()));
Assert.Single(((BugViewModel) response.Value).Comments);
}
}
So, the Test method I had as an example was Create_ResponseBodyIsCreatedBug but the question I have is regarding the second test method that I have created AddComment_CommentIsAddedtoViewModel().
What I am trying to do is:
you see that the BugService.AddComment -> it adds the comment with the Bug Guid we have provided and basically we return BugViewModel with that Comment added to the Comments collection.
test: that WHEN I add a BugComment it is returned in the ViewModel response and we have added exactly one Comment to the bug.
this line
var response = Assert.IsAssignableFrom<ObjectResult>(await sut.AddComment(Guid.Empty,new AddCommentForm()));
the response.Value is a BugViewModel with empty properties and the Comment property is empty without my inserted comment.
And on this line I get an exception as
Assert.Single(((BugViewModel) response.Value).Comments);
as the Comments property is null.
Look, at this line
_fixture.BugService.AddComment(Arg.Any<Guid>(), Arg.Any<AddCommentForm>())
.Returns(
new Option<BugViewModel>.Some(new BugViewModel()));
You setup your fake BugService to return an empty BugViewModel, which indeed would have Comments equal to null because you initialize it nowhere except FromData.
Use same approach you did in a first test
_fixture.BugService.AddComment(Arg.Any<Guid>(), Arg.Any<AddCommentForm>())
.Returns(
new Option<BugViewModel>.Some(
BugViewModel.FromData(FakeBug.I.Generate())));
Or introduce a constructor
public BugViewModel(Guid id, string title, string description, List<BugCommentViewModel> comments)
{
Id = id;
Title = title;
Description = description;
Comments = comments;
}
// Comments are not NULL now
public BugViewModel(): this(Guid.Empty, string.Empty, string.Empty, new List<BugCommentViewModel>())
{
}
In addition, I don't see any purpose of unit testing a mocked dependency of BugController .
Assert.Single(((BugViewModel) response.Value).Comments);
Better move this logic to a separate BugServiceTest which would validate the number of comments.
One more suggestion in regards to unit testing is instead of relying on ObjectResult, write better three tests:
[Fact]
public async Task AddComment_CommentIsAddedtoViewModel_Success()
{
_fixture.BugService.AddComment(Arg.Any<Guid>(), Arg.Any<AddCommentForm>())
.Returns(
new Option<BugViewModel>.Some(
BugViewModel.FromData(FakeBug.I.Generate())));
var sut = _fixture.GetSut();
Assert.IsAssignableFrom<OkResult>(
await sut.AddComment(Guid.Empty,new AddCommentForm()));
}
[Fact]
public async Task AddComment_BugNotFound()
{
_fixture.BugService.AddComment(Arg.Any<Guid>(), Arg.Any<AddCommentForm>())
.Returns(Option<BugViewModel>.None);
var sut = _fixture.GetSut();
Assert.IsAssignableFrom<NotFoundResult>(
await sut.AddComment(Guid.Empty,new AddCommentForm()));
}
public async Task AddComment_ThrowsForNonsenseData()
{
// Idk Option is value or reference type, so I use default(T)
_fixture.BugService.AddComment(Arg.Any<Guid>(), Arg.Any<AddCommentForm>())
.Returns(default(Option<BugViewModel>));
var sut = _fixture.GetSut();
await Assert.ThrowsAsync<InvalidOperationException>(
() => sut.AddComment(Guid.Empty, new AddCommentForm()));
}
Tell me if that helps
The problem is that you are mocking BugService.
You set mock to AddComment method and setup to return HARD CODED value.
That's why this your code is not called any more.
if (await DbBugs.SingleOrDefaultAsync(x => x.Id == bugId) is { } bug)
{
var bugComment = new BugComment
{
Text = form.Text,
Commenter = form.Commenter,
CommentedAt = DateTime.Now,
Bug = bug
};
await _dbContext.BugComments.AddAsync(bugComment);
await _dbContext.SaveChangesAsync();
return new Option<BugViewModel>.Some(BugViewModel.FromData(bug));
}
Your tests is written to check ONLY Controller.
if you want to check BugService too, you should NOT setup mocks for BugService and setup mocks to this:
DbBugs.SingleOrDefaultAsync(x => x.Id == bugId)
//and this
_dbContext.BugComments.AddAsync(bugComment);
//and this
_dbContext.SaveChangesAsync();
I have a class SendNotificationsToSubscribersCommandHandler with the following Method Handle and I have test method GetAllSubscriptionsWithCorrectParamsProductId() to check that Handle method returns correct List.
I get following error:
Message:
Test method Grand.Services.Tests.Commands.Handlers.Catalog.SendNotificationsToSubscribersCommandHandlerTest.GetAllSubscriptionsWithCorrectParamsProductId threw exception:
System.InvalidCastException: Unable to cast object of type 'System.Linq.EnumerableQuery`1[Grand.Domain.Catalog.BackInStockSubscription]' to type 'MongoDB.Driver.Linq.IMongoQueryable`1[Grand.Domain.Catalog.BackInStockSubscription]'.
Stack Trace:
MongoQueryable.Where[TSource](IMongoQueryable`1 source, Expression`1 predicate)
SendNotificationsToSubscribersCommandHandler
public class SendNotificationsToSubscribersCommandHandler : IRequestHandler<SendNotificationsToSubscribersCommand, IList<BackInStockSubscription>>
{
private readonly ICustomerService _customerService;
private readonly IWorkflowMessageService _workflowMessageService;
private readonly IRepository<BackInStockSubscription> _backInStockSubscriptionRepository;
public SendNotificationsToSubscribersCommandHandler(
ICustomerService customerService,
IWorkflowMessageService workflowMessageService,
IRepository<BackInStockSubscription> backInStockSubscriptionRepository)
{
_customerService = customerService;
_workflowMessageService = workflowMessageService;
_backInStockSubscriptionRepository = backInStockSubscriptionRepository;
}
public async Task<IList<BackInStockSubscription>> Handle(SendNotificationsToSubscribersCommand request, CancellationToken cancellationToken)
{
if (request.Product == null)
throw new ArgumentNullException("product");
int result = 0;
var query = _backInStockSubscriptionRepository.Table;
//product
query = query.Where(biss => biss.ProductId == request.Product.Id);
//warehouse
if (!string.IsNullOrEmpty(request.Warehouse))
query = query.Where(biss => biss.WarehouseId == request.Warehouse);
//warehouse
if (!string.IsNullOrEmpty(request.AttributeXml))
query = query.Where(biss => biss.AttributeXml == request.AttributeXml);
query = query.OrderByDescending(biss => biss.CreatedOnUtc);
var subscriptions = await query.ToListAsync();
//var subscriptions = await GetAllSubscriptionsByProductId(request.Product.Id, request.AttributeXml, request.Warehouse);
foreach (var subscription in subscriptions)
{
var customer = await _customerService.GetCustomerById(subscription.CustomerId);
//ensure that customer is registered (simple and fast way)
if (customer != null && CommonHelper.IsValidEmail(customer.Email))
{
var customerLanguageId = customer.GetAttributeFromEntity<string>(SystemCustomerAttributeNames.LanguageId, subscription.StoreId);
await _workflowMessageService.SendBackInStockNotification(customer, request.Product, subscription, customerLanguageId);
result++;
}
}
return subscriptions;
}
}
My test method:
[TestClass()]
public class SendNotificationsToSubscribersCommandHandlerTest
{
private Mock<ICustomerService> _mockCustomerService;
private Mock<IRepository<BackInStockSubscription>> _mockBackInStockSubscriptionRepository;
private Mock<IMongoQueryable<BackInStockSubscription>> _mongoQueryableMock;
private IQueryable<BackInStockSubscription> _expectedQueryable;
private List<BackInStockSubscription> _expected;
private Mock<IWorkflowMessageService> _mockWorkflowMessageService;
private SendNotificationsToSubscribersCommandHandler _handler;
private SendNotificationsToSubscribersCommand _sendNotificationsToSubscribersCommand;
[TestInitialize()]
public void Init()
{
_expected = new List<BackInStockSubscription>
{
new BackInStockSubscription { WarehouseId = "11", ProductId = "11" },
new BackInStockSubscription { WarehouseId = "11", ProductId = "11" }
};
_mockCustomerService = new Mock<ICustomerService>();
_mockBackInStockSubscriptionRepository = new Mock<IRepository<BackInStockSubscription>>();
_expectedQueryable = _expected.AsQueryable();
_mongoQueryableMock = new Mock<IMongoQueryable<BackInStockSubscription>>();
_mongoQueryableMock.As<IEnumerable<BackInStockSubscription>>();
_mongoQueryableMock.Setup(x => x.ElementType).Returns(_expectedQueryable.ElementType);
_mongoQueryableMock.Setup(x => x.Expression).Returns(_expectedQueryable.Expression);
_mongoQueryableMock.Setup(x => x.Provider).Returns(_expectedQueryable.Provider);
_mongoQueryableMock.Setup(x => x.GetEnumerator()).Returns(_expectedQueryable.GetEnumerator());
_mockBackInStockSubscriptionRepository.Setup(x => x.Table).Returns(_mongoQueryableMock.Object);
_mockWorkflowMessageService = new Mock<IWorkflowMessageService>();
_sendNotificationsToSubscribersCommand = new SendNotificationsToSubscribersCommand { Product = new Product { Id = "11"}, Warehouse = "11" };
_handler = new SendNotificationsToSubscribersCommandHandler(_mockCustomerService.Object, _mockWorkflowMessageService.Object, _mockBackInStockSubscriptionRepository.Object);
}
[TestMethod()]
public async Task GetAllSubscriptionsWithCorrectParamsProductId()
{
var result = await _handler.Handle(_sendNotificationsToSubscribersCommand, default);
var resultList = result.ToList();
Assert.AreEqual(resultList, _expected);
}
}
I get error on line
query = query.Where(biss => biss.ProductId == productId);
UPDATE
When I debug application, property _backInStockSubscriptionRepository.Table has Expression.Value = {aggregate([])}
If I debug test method property Table of Mock object has Expression.Value with Value = System.Collections.Generic.List<Grand.Domain.Catalog.BackInStockSubscription> with my two objects.
Any help is greatly appreciated
Take a look at here: How to mock a class that implements multiple interfaces
Try something like this:
_mongoQueryableMock = new Mock<IMongoQueryable<BackInStockSubscription>>();
_mongoQueryableMock.As<IEnumerable<BackInStockSubscription>>();
...
I am trying to test one of my methods by seeing how many results are being passed into my Save method. The pertinent line is:
await paymentSampleRepository.Received()
.SaveSamplesAsync(Arg.Do<List<PaymentSamplePopulation>>(x =>
Assert.Equal(sampleCount, x.Count())
), modifiedBy);
I am obviously missing something about how to test this... how do I test the Count of what's being passed into SaveSamplesAsync
This is always showing as passing. I've tried sampleCount and sampleCount + 1 in the Assert and they both show as passing!
If need be, I can show the whole test method.
Reference Actions with argument matchers
Assuming following
public interface ILoader {
Task LoadAsync(List<int> data);
}
public class SystemUnderTest {
private readonly ILoader loader;
public SystemUnderTest(ILoader loader) {
this.loader = loader;
}
public async Task InvokeAsync(int count) {
var data = Enumerable.Range(1,count).ToList();
await loader.LoadAsync(data);
}
}
A test would look like this
//Arrange
var expected = 2;
var actual = -1;
var loader = Substitute.For<ILoader>();
loader.LoadAsync(Arg.Do<List<int>>(x => actual = x.Count);
var sut = new SystemUnderTest(loader);
//Act
await sut.InvokeAsync(expected);
//Assert
Assert.Equal(expected, actual);
Is there a way to setup and verify a method call that use an Expression with Moq?
The first attempt is the one I would like to get it to work, while the second one is a "patch" to let the Assert part works (with the verify part still failing)
string goodUrl = "good-product-url";
[Setup]
public void SetUp()
{
productsQuery.Setup(x => x.GetByFilter(m=>m.Url== goodUrl).Returns(new Product() { Title = "Good product", ... });
}
[Test]
public void MyTest()
{
var controller = GetController();
var result = ((ViewResult)controller.Detail(goodUrl)).Model as ProductViewModel;
Assert.AreEqual("Good product", result.Title);
productsQuery.Verify(x => x.GetByFilter(t => t.Url == goodUrl), Times.Once());
}
Thet test fail at the Assert and throw a null reference exception, because the method GetByFilter is never called.
If instead I use this
[Setup]
public void SetUp()
{
productsQuery.Setup(x => x.GetByFilter(It.IsAny<Expression<Func<Product, bool>>>())).Returns(new Product() { Title = "Good product", ... });
}
The test pass the Assert part, but this time is the Verify that fail saying that it is never called.
Is there a way to setup a method call with a specific expression instead of using a generic It.IsAny<>()?
Update
I tried also the suggestion by Ufuk Hacıoğulları in the comments and created the following
Expression<Func<Product, bool>> goodUrlExpression = x => x.UrlRewrite == "GoodUrl";
[Setup]
public void SetUp()
{
productsQuery.Setup(x => x.GetByFilter(goodUrlExpression)).Returns(new Product() { Title = "Good product", ... });
}
[Test]
public void MyTest()
{
...
productsQuery.Verify(x => x.GetByFilter(goodUrlExpression), Times.Once());
}
But I get a null reference exception, as in the first attempt.
The code in my controller is as follow
public ActionResult Detail(string urlRewrite)
{
//Here, during tests, I get the null reference exception
var entity = productQueries.GetByFilter(x => x.UrlRewrite == urlRewrite);
var model = new ProductDetailViewModel() { UrlRewrite = entity.UrlRewrite, Culture = entity.Culture, Title = entity.Title };
return View(model);
}
The following code demonstrates how to test in such scenarios. The general idea is that you execute the passed in query against a "real" data. That way, you don't even need "Verify", as if the query is not right, it will not find the data.
Modify to suit your needs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Moq;
using NUnit.Framework;
namespace StackOverflowExample.Moq
{
public class Product
{
public string UrlRewrite { get; set; }
public string Title { get; set; }
}
public interface IProductQuery
{
Product GetByFilter(Expression<Func<Product, bool>> filter);
}
public class Controller
{
private readonly IProductQuery _queryProvider;
public Controller(IProductQuery queryProvider)
{
_queryProvider = queryProvider;
}
public Product GetProductByUrl(string urlRewrite)
{
return _queryProvider.GetByFilter(x => x.UrlRewrite == urlRewrite);
}
}
[TestFixture]
public class ExpressionMatching
{
[Test]
public void MatchTest()
{
//arrange
const string GOODURL = "goodurl";
var goodProduct = new Product {UrlRewrite = GOODURL};
var products = new List<Product>
{
goodProduct
};
var qp = new Mock<IProductQuery>();
qp.Setup(q => q.GetByFilter(It.IsAny<Expression<Func<Product, bool>>>()))
.Returns<Expression<Func<Product, bool>>>(q =>
{
var query = q.Compile();
return products.First(query);
});
var testController = new Controller(qp.Object);
//act
var foundProduct = testController.GetProductByUrl(GOODURL);
//assert
Assert.AreSame(foundProduct, goodProduct);
}
}
}