Moq: How to return result depending on the method parameter? - moq

ICustomerRepository define: Customer GetCustomerByID(int CustomerID);
//Arrange
var customers = new Customer()
{
new Customer() { CustomerID = 1, Name = "Richard" },
new Customer() { CustomerID = 2, Name = "Evan" },
new Customer() { CustomerID = 3, Name = "Marie-France" },
}.AsQueryable();
Mock<ICustomerRepository> mock = new Mock<ICustomerRepository>();
How do I tell Moq to return the correct customer depending on the CustomerID paremeter???
I've been able to set up the first part, but not the return object.
mock.Setup(m => m.GetCustomerByID(It.Is<int>(i => i >= 0))).Returns(/// To be define///)
The Idea is to have the same result as this:
public Customer GetCustomerByID(int CustomerID)
{
return customers.FirstOrDefault(c => c.CustomerID == CustomerID);
}
Thanks for helping

mock.Setup(x => x.GetCustomerByID(It.IsAny<int>()))
.Returns((int id) =>
customers.FirstOrDefault(c => c.CustomerID == id));
Just make customers a List<Customer> - no need for AsQueryable.

Related

Cannot applied to Operands of Type 'IEnumerable<DateTime>' and `DateTime` ( >= & <=)

I have the following linq expression i was trying to convert string to Date and make a comparison as shown below but it gives the this error
Here is my Linq expression looks like
var ProjectList = Context.Project.AsNoTracking()
.Include(ca => ca.Cost)
.Where(p => p.Cost.Select(ca => DateTime.ParseExact(ca.MonthYYYYMM, "yyyyMM", CultureInfo.InvariantCulture)) <= request.ToDate && DateTime.ParseExact(ca.MonthYYYYMM, "yyyyMM", CultureInfo.InvariantCulture)) >= request.FromDate)
.ToListAsync();
I have the [MonthYYYYMM] in a database as a char type
[MonthYYYYMM] [char](8) NOT NULL,
How can i convert string to date and make the comparison?
Try this
var ProjectList = Context.Project.AsNoTracking()
.Include(ca => ca.Cost)
.Where(p => p.Cost.Select(ca => (DateTime.ParseExact(ca.MonthYYYYMM, "yyyyMM", CultureInfo.InvariantCulture))
<= request.ToDate) && (DateTime.ParseExact(ca.MonthYYYYMM, "yyyyMM", CultureInfo.InvariantCulture)) >= request.FromDate))
.ToListAsync();
() parenthesis around the expression you want to evaluate/compare.
my friend. Here is a sample. Hope to help :))
class Project
{
public List<Cost> Costs { get; set; }
}
class Cost
{
public string MonthYYYYMM { get; set; }
public double Price { get; set; }
}
var data = new List<Project>()
{
new Project()
{
Costs = new List<Cost>()
{
new Cost(){ MonthYYYYMM = "202007", Price = 10},
new Cost(){ MonthYYYYMM = "202008" , Price = 20},
new Cost(){ MonthYYYYMM = "202009" , Price = 30},
new Cost(){ MonthYYYYMM = "202010" , Price = 40}
}
}
};
var fromDate = DateTime.Now;
var endDate = DateTime.Now.AddMonths(1);
var projectList = data.Select(t=> new Project()
{
Costs = t.Costs.Where(c=>
DateTime.ParseExact(c.MonthYYYYMM, "yyyyMM", CultureInfo.InvariantCulture) >= fromDate
&& DateTime.ParseExact(c.MonthYYYYMM, "yyyyMM", CultureInfo.InvariantCulture) <= endDate) .ToList()
});
p.Cost.Select(ca => DateTime.ParseExact(ca.MonthYYYYMM, "yyyyMM", CultureInfo.InvariantCulture))
Select() return IEnumerable<DateTime>.That's main reason of error.
var ProjectList = Context.Project.AsNoTracking()
.Include(ca => ca.Cost)
.Where(ca => DateTime.ParseExact(ca.Cost.MonthYYYYMM, "yyyyMM", CultureInfo.InvariantCulture) <= request.ToDate && DateTime.ParseExact(ca.Cost.MonthYYYYMM, "yyyyMM", CultureInfo.InvariantCulture) >= request.FromDate)
.ToListAsync();
UPDATE
public class Cost
{
public int Id { get; set; }
public char[] MonthYYYYMM { get; set; }
public int projectId { get; set; }
public DateTime getDate() {
return DateTime.ParseExact(this.MonthYYYYMM, "yyyyMM", CultureInfo.InvariantCulture);
}
}
var ProjectList = Context.Project.AsNoTracking()
.Include(ca => ca.Cost)
.Where(
p => p.Cost.Any(c => c.getDate() <= ToDate && c.getDate() >= FromDate)
).ToListAsync();
It works.

how to assign value to entity got from database

I have a linq query like below:
public IQueryable<vmEmp> GetEmp(int crewid)
{
var dt = new EmpEntities();
var e = from t in dt.tblEmp
where (t.CrewId == crewid)
select new vmEmp
{
Id = -1,
Crew = t.crewid,
Name = t.Name,
Address = t.Address
};
return e;
}
I hope can make the Id auto decrease by 1 till end of the employee.
like first's Id is -1, second's is -2, third is -3 ...
How to do that here? Thanks a lot
If this was LINQ-to-objects, you could use this overload of Select:
var dt = new EmpEntities();
var e = dt.tblEmp
.Where(t => t.CrewId == crewid)
.Select((t,index) => new vmEmp
{
Id = -index - 1,
Crew = t.crewid,
Name = t.Name,
Address = t.Address
});
But EF doesn't suport this, because the indexer can't be translated into SQL. So you need a work-around:
var dt = new EmpEntities();
var e = dt.tblEmp
.Where(t => t.CrewId == crewid)
.Select(t => new
{
Id = 0,
Crew = t.crewid,
Name = t.Name,
Address = t.Address
}
.AsEnumerable() // Continue in memory
.Select((t,index) => new vmEmp
{
Id = -index - 1,
Crew = t.Crew,
Name = t.Name,
Address = t.Address
});
Side note: it's recommended to put dt in a using construct.
Use a counter variable and decrease it for every record while you project it to your custom POCO.
public IQueryable<vmEmp> GetEmp(int crewid)
{
int counter=0;
var dt = new EmpEntities();
//load the items to a list of anonymous type
var eList = from t in dt.tblEmp
where (t.CrewId == crewid)
.Select(s=>
new { Id = 0,
Crew = s.crewid,
Name = s.Name,
Address = s.Address
}).ToList();
var e=eList.Select(x=> new vmEmp
{
Id = --counter,
Crew = x.Crew,
Name = x.Name,
Address = x.Address
});
return e.AsQueryable();
}

Bind a list returned from a LINQ query to Gridview

I have a linq query something like this
var Query = from c in table
where (some condition)
select new {
Name = c.Name,
courses = // this returns a list,
};
How do I bind this to gridview so that the result is like this
name1 course1
name1 course2
name1 course3
name2 course1
name2 course2
Any ideas?
try below
gridview.DataSource = Query.ToList().Select(a => a.courses
.Select(c => new { Name = a.Name, Course = c }))
.SelectMany(p=>p).ToList();
gridview.DataBind();
If you want to return this list from method then create class as below
public class MyClass
{
public string Name { get; set; }
public string Course { get; set; }
}
now you can return list as
public List<MyClass> MyMethod()
{
var Query = from c in table
where (some condition)
select new {
Name = c.Name,
courses = // this returns a list,
};
return Query.ToList().Select(a => a.courses
.Select(c => new MyClass{ Name = a.Name, Course = c }))
.SelectMany(p=>p).ToList();
}

Routing issue in asp.net mvc 3. Displays items by category, but doesn't display all items

I want to display items by categories. I use linq and everything works except of that I can't display all items regardless category. Probably routing issue, cause I've already asked question about linq expression that i use, and it should be fine. Anyway, here is my code:
public ViewResult Content(string category, int page = 1)
{
var model = new StoreContentViewModel
{
Items = _itemsRepository.GetItems()
.Where(i => i.Product.Category == null ||
i.Product.Category != null && i.Product.Category == category)
.OrderBy(i => i.ItemId)
.Skip((page - 1) * PageSize)
.Take(PageSize)
.Select(i => i),
}
}
And the RegisterRouts method's contents:
// without categories
routes.MapRoute(
null,
"Store/Content/Page{page}",
new { controller = "Store", action = "Content", category = (string)null},
new { page = #"\d+" });
// with categories
routes.MapRoute(
null,
"Store/Content/{category}/Page{page}",
new { controller = "Store", action = "Content" },
new { page = #"\d+" });
// Default route
routes.MapRoute(
null,
"{controller}/{action}",
new { controller = "Home", action = "Index"});
I'm confused of the order of "with and without categories" routs.
The thing is when I enter URL:
~/Store/Content
or:
~/Store/Content/Page1 // or Page2
items are not displayed. But if I enter:
~/Store/Content/Man's-Shoes/Page1
the items that are associated with "Man's-Shoes" category are displayed.
So, do this issue has something to do with routs or mabby there is another problem??
p.s. I've been takling this issue for the last 2 days, so any help would be appropriate.
Edited:
And also there is this unit test that fails. Probably it is badly written. Check it also.
In my model I have Items entity that "contains" Products and Shipping entities:
[TestMethod]
public void Can_Filter_Content()
{
//Arrange
private Mock<IItemsRepository> _itemsMock = new Mock<IItemsRepository>();
private Mock<IProductRepository> _productsMock = new Mock<IProductRepository>();
private Mock<IShippingRepository> _shippingMock = new Mock<IShippingRepository>();
_itemsMock.Setup(i => i.GetItems()).Returns(new[]
{
new Item { ItemId = 1, ProductId = 1, ShippingId = 1},
new Item { ItemId = 2, ProductId = 2, ShippingId = 2},
new Item { ItemId = 3, ProductId = 3, ShippingId = 3},
new Item { ItemId = 4, ProductId = 4, ShippingId = 4}
});
_productsMock.Setup(p => p.GetProducts()).Returns(new[]
{
new Product { ProductId = 1, Category = "shoes"},
new Product { ProductId = 2, Category = "shoes"},
new Product { ProductId = 3, Category = "superShoes"},
new Product { ProductId = 4, Category = "shoes"}
});
var controller = new StoreController(_itemsMock.Object,
_productsMock.Object, _shippingMock.Object) {PageSize = 2};
// Act
Item[] result = ((StoreContentViewModel) controller.Content(null).Model).Items.ToArray();
ViewResult viewResult = controller.Content(null);
// Assert
Assert.IsTrue(result[0].ItemId == 1 && result[1].ItemId == 2);
Assert.AreEqual(result.Length, 2);
Assert.AreEqual("", viewResult.ViewName);
}
Mabby this helps
Should this:
.Where(i => i.Product.Category == null ||
i.Product.Category != null && i.Product.Category == category)
Be this:
.Where(i => category == null ||
i.Product.Category != null && i.Product.Category == category)
When category is null, the original condition says where the product category is not null, and that category matches null, which will never work. The new condition says if the category is null, don't evaluate the condition; otherwise, match on the category ("Man's-Shoes").

nhibernate "join"

is any way to optimize this solution?
whether there is any possibility of obtaining the same result by calling single query?
public List<Company> GetCompanies(DateTime maxDate, int stockQuotesCount)
{
List<Company> result = new List<Company>();
IList<Company> company = null;
DateTime lastSessionDate = new StockQuoteRepository().GetLastSessionDate(maxDate);
using (ISession s = DataAccessFacade.OpenSesion())
{
String sqlQuery = string.Empty;
sqlQuery = #"Select
*
From
dbo.Company c
Where
c.Company_FirstQuotationDate <= :date and
(c.Company_LastQuotationDate >= :date or c.Company_LastQuotationDate is Null)
Order By
c.Company_Name asc";
company = s.CreateSQLQuery(sqlQuery)
.AddEntity(typeof(Company))
.SetDateTime("date", lastSessionDate)
.List<Company>();
if (company != null)
{
for (int i = 0; i < company.Count; i++)
{
sqlQuery = #"Select
Top(:top)
*
From
dbo.StockQuote sq
Where
sq.StockQuote_Company_Id = :cId
and sq.StockQuote_Date <= :date
Order By
sq.StockQuote_Date desc";
company[i].StockQuotes = s.CreateSQLQuery(sqlQuery)
.AddEntity(typeof(StockQuote))
.SetParameter<int>("cId", company[i].Id)
.SetParameter<int>("top", stockQuotesCount)
.SetDateTime("date", lastSessionDate)
.List<StockQuote>();
}
}
}
return (List<Company>)company;
}
my fluent mapings:
public class CompanyMap : ClassMap<Company>
{
public CompanyMap()
{
this.Id(x => x.Id).Column("Company_Id");
this.Map(x => x.Name).Column("Company_Name");
this.Map(x => x.FirstQuotationDate).Column("Company_FirstQuotationDate");
this.Map(x => x.LastQuotationDate).Column("Company_LastQuotationDate");
this.HasMany(x => x.StockQuotes)
.Cascade.All()
.BatchSize(50)
.Inverse();
}
}
public class StockQuoteMap : ClassMap<StockQuote>
{
public StockQuoteMap()
{
this.Id(x => x.Id).Column("StockQuote_Id");
this.Map(x => x.Open).Column("StockQuote_Open");
this.Map(x => x.Low).Column("StockQuote_Low");
this.Map(x => x.High).Column("StockQuote_High");
this.Map(x => x.Close).Column("StockQuote_Close");
this.Map(x => x.Volume).Column("StockQuote_Volume");
this.Map(x => x.Date).Column("StockQuote_Date");
this.References(x => x.Company).Column("Company_Id");
}
}
ok, it is better query
using (ISession s = DataAccessFacade.OpenSesion())
{
String cHql = #"select
distinct c
from
Company c
join fetch c.StockQuotes s
where
c.FirstQuotationDate <= :maxDate and
(c.LastQuotationDate >= :maxDate or c.LastQuotationDate is Null)
and s.Date >= :minDate
order by
c.Name asc,
s.Date desc";
result = s.CreateQuery(cHql)
.SetDateTime("maxDate", lastSessionDate)
.SetDateTime("minDate", lastSessionDate.AddMonths(-2))
.List<Company>().ToList();
}
but there is one problem,
instead of giving time period for selecting StockQuote by StockQuote.Date form Company.StockQuotes, wants to make the TOP() on this joined collection
really, I only know maxDate (in this case), the calculation minDate is very difficult

Resources