How to write unit test for mvc. In class a method return a list? - asp.net-mvc-4

I need to write unit test for below code. Easy understanding of the solution. I novice for unit testing. I don't know how write. I have added unit test class successfully from solution explorer.
class 1:
public class ListModel
{
public int EmpID { get; set; }
public string EmpName {get;set;}
public string CusID {get; set;}
public string EmpType { get; set; }
public string EmpPDLC { get; set; }
public int? EmpMode { get; set; }
public int? Status { get; set; }
}
class 2:
public class EmployeeHelper : IEmployeeHelper
{
public List<ListModel> EmployeeList(int userId)
{
var lstModel = new List<ListModel>();
try
{
using (var dc = new EmployeeDataContext())
{
var lstGetTable = (from table in dc.UserTables
where table.UserID == userId && table.Status == 1
select table).ToList();
lstModel.AddRange(lstGetTable.Select(items => new ListModel
{
EmpID = items.EmpID,
EmpName = items.EmpName,
CustID = items.CustID,
EmpType = items.EmpType,
EmpPDLC = items.EmpPDLC,
EmpMode = items.EmpMode,
Status = items.Status
}));
}
}
catch (Exception)
{
return lstModel;
}
return lstModel;
}
}

Related

Convert Generic API Response in Blazor

I'm developing a Blazor WASM project and I'm stuck in this point.
I'm using a DataAccess Service to make the requests to EndPoints;
The endpoints return a ResultList, that is a Generic Object that needs to be parsed in Client side. The object definition:
public class ResultList
{
public ResultList(List<object> resultados, string codigoErro = null, string mensagemErro = null)
{
this.Resultados = resultados;
this.CodigoErro = codigoErro;
this.MensagemErro = mensagemErro;
}
public string MensagemErro { get; set; }
public List<object> Resultados { get; set; }
public string CodigoErro { get; set; }
}
In the client side, I receive the same type:
public async Task<ResultList> GetEmpresas()
{
try
{
ResultList Result = await _httpClient.GetFromJsonAsync<ResultList>("api/EmpCadBasico/GetEmpresas");
return Result;
}
catch (Exception ex)
{
return new ResultList(null, null, ex.Message);
}
}
The problem is: I can't convert the List<Object> to other type like List<Empresa>.
The C# compilation doesn't notify bug, but in execution time, it happens.
I tried Serialize and Deserialize, and it doesn't work too:
public async Task GetEmpresas()
{
ResultList Resultado = await _dataAccess.GetEmpresas();
if (await RetornoOk(Resultado))
{
string x = JsonSerializer.Serialize(Resultado.Resultados); // Here, that's fine.
List<Empresa> y = JsonSerializer.Deserialize<List<Empresa>>(x); // Here, it finds the objects, but all of them with null values.
}
}
The X value: '[{"id":1,"nomeEmpresa":"Alamo","cnpj":"00072619000101","dataCadastro":"2020-01-01T00:00:00","colaborador":[],"marca":[]}]'
The Y value: Y value after Deserialization
According to the json return data you provided, I did the following restoration and successfully returned the data, you can refer to it.
Model:
public class TestModel
{
public int id { get; set; }
public string nomeEmpresa { get; set; }
public string cnpj { get; set; }
public string dataCadastro { get; set; }
public List<colaborador> colaborador { get; set; }
public List<marca> marca { get; set; }
}
public class colaborador
{
public int id { get; set; }
public string test { get; set; }
}
public class marca
{
public int id { get; set; }
public string test { get; set; }
}
Then I gave values to individual attributes, and the results are as follows:

Net Core 2.1 Controller truncates Json while the json has no reference loops

I'm struggling with net core returning truncated response. I have already defined no reference loop in my startup services, and also tried to set compatibility version for the version i'm currently using 2.1 as follows:
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddJsonOptions(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
I also tried to serialize the array using JsonConvert and it did not throw any reference loop exception. Here's the action in the controller and the serializedArray text:
public IActionResult GetProductItems(int productId)
{
try
{
var productItems = _productsMethods.GetProductItems(productId);
// for testing the object for ref loops
string serialized = Newtonsoft.Json.JsonConvert.SerializeObject(productItems);
return Ok(productItems);
}
catch (ClientException ex)
{
return BadRequest(new { message = ex.Message });
}
catch (Exception ex)
{
return StatusCode(500, new { message = ex.Message });
}
}
// serialized string
//[{"ID":2,"ProductId":6,"ItemId":4,"Product":null,"Item":null,"Orders":[]},{"ID":3,"ProductId":":6,"ItemId":1,"Product":null,"Item":null,"Orders":[]},{"ID":5,"ProductId":":6,"ItemId":2,"Product":null,"Item":null,"Orders":[]}]
Here's the actual response
[{"id":2,"productId":6,"itemId":4,"product":null,"item":null,"orders":
Method:
public List<ProductItem> GetProductItems(int productId)
{
IQueryable<DataSets.ProductItem> query = db.ProductItems
.AsNoTracking()
.Include(k => k.Orders)
.Where(k => k.ProductId == productId);
// result truncated (when array orders is empty)
//return query.Select(_mapper.Map<ProductItem>).ToList();
// without automapper, also truncated
//return query.Select(k => new ProductItem()
//{
// ID = k.ID,
// ItemId = k.ItemId,
// ProductId = k.ProductId,
// Orders = k.Orders.Select(a => new Order() { ID = a.ID })
// .ToList()
//}).ToList();
// WORKS, not getting truncated
// order not included
return query.Select(k => new ProductItem()
{
ID = k.ID,
ItemId = k.ItemId,
ProductId = k.ProductId,
}).ToList();
}
Entities (renamed and removed props for simplification):
public class Product
{
public int ID { get; set; }
// some props
public string UserId { get; set; }
public User User { get; set; }
public List<ProductItem> Items { get; set; }
}
public class ProductItem
{
public int ID { get; set; }
// some props
public int ProductId { get; set; }
public int ItemId { get; set; }
public Product Product { get; set; }
public Item Item { get; set; }
public List<Order> Orders { get; set; }
}
public class Order
{
public int ID { get; set; }
// some props
public int ItemId { get; set; }
public ProductItemOrder Item { get; set; }
}
Since there is no reference loop in orders and also the reference loop is ignored. Why is this still truncating?
I think the problem is public Product Product { get; set; } part here. You should define your Product entity virtually.
Here is an example below,
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public string Tags { get; set; }
public virtual ICollection<Post> Posts { get; set; }
}
Here is source.
For someone who might have this issue in the future. While I think the API should throw that error instead of just truncating the response.
I had 2 properties with the same letters but different letter case IPAddress and IpAddress.
SerializeObject alone wasn't throwing an exception, then I did this (CamelCase Resolver) to point out the issue:
Newtonsoft.Json.JsonConvert.DefaultSettings = () => new Newtonsoft.Json.JsonSerializerSettings
{
NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver()
};
string serialized = Newtonsoft.Json.JsonConvert.SerializeObject(productItems);
So it threw: A member with the name 'ipAddress' already exists on ...

Can i add a parent record and a child record using the same _context.SaveChangesAsync()

I have the following 2 Parent/Child objects:-
public Submission()
{
SubmissionQuestionSubmission = new HashSet<SubmissionQuestionSubmission>();
}
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Npi { get; set; }
public bool Independent { get; set; }
public string Comment { get; set; }
public virtual ICollection<SubmissionQuestionSubmission> SubmissionQuestionSubmission { get; set; }
}
public partial class SubmissionQuestionSubmission
{
public int SubmissionQuestionId { get; set; }
public int SubmissionId { get; set; }
public string Answer { get; set; }
public virtual Submission Submission { get; set; }
}
and i created the following view model:-
public class SubmissionCreate
{
public Submission Submission {set; get;}
public IList<SubmissionQuestion> SubmissionQuestion { set; get; }
public IList<SubmissionQuestionSubmission> SubmissionQuestionSubmission { set; get; }
}
where i have the following action method to add a parent record (submission) and a child record (SubmissionQuestionSubmission ), but to do so, i have to issue 2 save requests to the database, one to save the parent and get its ID, while the other to save the child record and assign it the parent ID, as follow:-
public async Task<IActionResult> Create(SubmissionCreate sc)//Bind("Id,FirstName,LastName,Npi,Independent,Comment")]
{
if (ModelState.IsValid)
{
var newsubmission = _context.Submission.Add(sc.Submission);
await _context.SaveChangesAsync();
foreach (var v in sc.SubmissionQuestionSubmission)
{
v.SubmissionId = sc.Submission.Id;
_context.SubmissionQuestionSubmission.Add(v);
}
await _context.SaveChangesAsync();
TempData["message"] = "Thank You.. Your request has been submitted...";
return View("Confirmation");
}
return View(sc);
}
so my question is if i can do the above job, using one save statement instead of 2?
You don't need use two SaveChanges. You can assign newsubmission into Submission property instead of v.SubmissionId = sc.Submission.Id;.
In this case Id and ForeignKey created automatically by EF Core
var newsubmission = _context.Submission.Add(sc.Submission);
foreach (var v in sc.SubmissionQuestionSubmission)
{
v.Submission = newsubmission;
_context.SubmissionQuestionSubmission.Add(v);
}
await _context.SaveChangesAsync();
Another way
sc.Submission.SubmissionQuestionSubmission = new List<SubmissionQuestionSubmission>();
foreach (var v in sc.SubmissionQuestionSubmission)
{
sc.Submission.SubmissionQuestionSubmission.Add(v)
}
_context.Submission.Add(sc.Submission);
await _context.SaveChangesAsync();

Take function doesn't work and cannot be sent to RavenDB for query

Query Code:
var query = session.IndexQuery<App_OrgSearch.IndexResult, App_OrgSearch>();
var organizationUnitResults = query.Statistics(out stats)
.Skip(0)
.Take(5)
.AsProjection<Org>().ToList();
public static IRavenQueryable<TResult> IndexQuery<TResult, TIndex>(this IDocumentSession session)
where TIndex : AbstractIndexCreationTask, new()
{
return session.Query<TResult, TIndex>();
}
App_OrgSearch is the index I defined as below:
public class App_OrgSearch : AbstractIndexCreationTask<Org, App_OrgSearch.IndexResult>
{
public class IndexResult
{
public string Id { get; set; }
public string BusinessName { get; set; }
public string ShortName { get; set; }
public IList<string> Names { get; set; }
public List<string> PhoneNumbers { get; set; }
public List<OrganizationUnitPhone> OrganizationUnitPhones { get; set; }
}
public App_OrganizationUnitSearch()
{
Map = docs => from doc in docs
select new
{
Id = doc.Id,
Names = new List<string>
{
doc.BusinessName,
doc.ShortName,
},
BusinessName = doc.BusinessName,
ShortName = doc.ShortName,
PhoneNumbers = doc.OrganizationUnitPhones.Where(x => x != null && x.Phone != null).Select(x => x.Phone.Number),
};
Indexes.Add(x => x.Names, FieldIndexing.Analyzed);
}
}
I have 27 records in database. I want to take 5, but after query, all 27 records are returned. Why does Take function not work?
Your sample code seems wrong.
var query = session.IndexQuery<App_OrgSearch.IndexResult, App_OrgSearch>();
var organizationUnitResults = organizationUnitsQuery.Statistics(out stats)
What is organizationUnitsQuery ? You have the query as query, but there is no IndexQuery method on the session

ASP.NET MVC query lambda expression

Hello I have problem in one query. Why it's always return no value.
public List<UserDetail> userSearchModel(UserSearchModel searchModel)
{
string userid = User.Identity.GetUserId();
var user = _dbContext.UserDetails.Where(x => x.Id == userid);
var result = _dbContext.UserDetails.Except(user).ToList().AsQueryable();
if (searchModel != null)
{
if (searchModel.LanguageId.Count() != 0)
{
List<UserDetailLanguage> usrDetails = new List<UserDetailLanguage>();
foreach (var item in searchModel.LanguageId)
{
var details = _dbContext.UserDetailLanguages.Where(x => x.LanguageId == item).ToList();
foreach (var item2 in details)
{
usrDetails.Add(item2);
}
}
result = result.Where(x => x.UserDetailLanguages == usrDetails);
}
}
return result.ToList();
}
I want to get results which are the same in usrDetails list and in result.UserDetailLanguages.
In result.UserDetailLanguages I have record equals to record in usrDetails but this not want retrieve.
Here is my model:
public class UserDetail
{
public UserDetail()
{
this.UserDetailLanguages = new HashSet<UserDetailLanguage>();
}
[Key, ForeignKey("User")]
public string Id { get; set; }
public DateTime Birthday { get; set; }
public string Sex { get; set; }
public string Country { get; set; }
public string About { get; set; }
[NotMapped]
public int Age { get { return DateTime.Now.Year - Birthday.Year; } }
public virtual ApplicationUser User { get; set; }
public virtual ICollection<UserDetailLanguage> UserDetailLanguages { get; set; }
}
public class UserDetailLanguage
{
public Int32 Id { get; set; }
public virtual UserDetail UserDetail { get; set; }
public string UserDetailId { get; set; }
public virtual Language Language { get; set; }
public Int32 LanguageId { get; set; }
public Boolean IsKnown { get; set; }
public static implicit operator List<object>(UserDetailLanguage v)
{
throw new NotImplementedException();
}
}
public class Language
{
public Language()
{
this.UserDetailLanguages = new HashSet<UserDetailLanguage>();
}
public int Id { get; set; }
public string Value { get; set; }
public string Name { get; set; }
public virtual ICollection<UserDetailLanguage> UserDetailLanguages { get; set; }
}
What I'm doing wrong?
If you want to see if your value is in a list you use the Contains function of the list -- like this:
result = result.Where(x => usrDetails.Contains(x.UserDetailLanguage));
If you want to see if there are any items in both lists you can use intersection like this:
result = result.Where(x => usrDetails.Intersect(x.UserDetailLanguage).Count() > 0);
Looks like you are checking equality between lists in following code
result = result.Where(x => x.UserDetailLanguages == usrDetails);
This might not work, to check equality for lists you can use something like
Enumerable.SequenceEqual(FirstList.OrderBy(fList => fList),
SecondList.OrderBy(sList => sList))