How to test is an "If loop" in UnitTestcase Xunit C# - c#

I have a Rest API endpoint. And I want to check if the loop is executing in the Unit test case Following is my code. But if (days > 365) part I not covered in my unit test case. how to include that part in the unit test case
[HttpPost, Route("v1/test")]
public async Task<IActionResult> Run(Request request)
{
var days = (request.ToDate - request.FromDate).TotalDays;
var today = new MonthMap(request.ToDate.UtcDateTime.Month, request.ToDate.UtcDateTime.Day);
var fromDay = new MonthMap(request.FromDate.UtcDateTime.Month, request.FromDate.UtcDateTime.Day);
if (days > 365)
{
fromDay = new MonthMap(1, 1);
today = new MonthMap(12, 31);
}
var query = new Query
{
ToDay = today,
FromDay = fromDay
};
var today = DateTimeOffset.UtcNow;
var results = await _valueService.GetResult(query, today);
return new OkObjectResult(results);
}
}
public MonthMap(int month, int day)
{
if (month > 12 || month < 1)
{
throw new ArgumentException(" number between 1 and 12");
}
if (day < 1 || day > 31)
{
throw new ArgumentException("number between 1 and 31");
}
Day = day;
Month = month;
Unittest
[Fact]
public async Task Test_Run_When_Day_Greater_Than_365()
{
// Arrange
var request = new Request
{
FromDate = new DateTimeOffset(2022, 1, 1, 0, 0, 0, TimeSpan.Zero),
ToDate = new DateTimeOffset(2022, 12, 31, 0, 0, 0, TimeSpan.Zero),
};
var mockValueService = new Mock<IValueService>();
var mockLogger = new Mock<ILogger<ReportsController>>();
var controller = new ReportsController(mockValueService .Object, mockLogger.Object);
mockValueService .Setup(x => x.GetResult(It.IsAny<Query>(),It.IsAny<DateTimeOffset>()))
.ReturnsAsync(new List<MonthLyDataModel>
{new IresultModel{ Id = "1", Result= "CO1", Month= "1" },
{new IresultModel{ Id = "1", Result= "CO1", Month= "2" },
{new IresultModel{ Id = "1", Result= "CO1", Month= "3" },
{new IresultModel{ Id = "1", Result= "CO1", Month= "4" },
{new IresultModel{ Id = "1", Result= "CO1", Month= "5" },
{new IresultModel{ Id = "1", Result= "CO1", Month= "6" },
{new IresultModel{ Id = "1", Result= "CO1", Month= "7" },
{new IresultModel{ Id = "1", Result= "CO1", Month= "8" },
{new IresultModel{ Id = "1", Result= "CO1", Month= "9" },
{new IresultModel{ Id = "1", Result= "CO1", Month= "10" },
{new IresultModel{ Id = "1", Result= "CO1", Month= "11" },
{new IresultModel{ Id = "1", Result= "CO1", Month= "12" },
});
// Act
var result = await controller. Run(request);
Assert.IsType<OkObjectResult>(result);
var resultObject = (OkObjectResult)result;
var resultJson = (List<MonthLyDataModel>)resultObject.Value;
Assert.Equal(resultJson.Count, 12);
}
My unit test is not actually covered the loop. Its just counting only the dummy data. Is it possible to check this part of code?. If yes, how to do that?

Related

GroupBy bool and Select values for new list

I am trying to get into more complex Linq queries and right away catch a point I am feeling stuck. I have a following list in DB:
ID ELAPSED TIME APPISRUNNING
1 12 TRUE
2 54 TRUE
3 32 FALSE
Where ELAPSED TIME is TimeSpan and APPISRUNNING is a bool.
I would like to build a chart based on these values (https://github.com/beto-rodriguez/LiveCharts2). Chart build fine with this:
Title = "Analytics";
this.ActivityChartSeries = new ISeries[]
{
new PieSeries<double> { Values = new double[] { 2 }},
new PieSeries<double> { Values = new double[] { 2 }},
new PieSeries<double> { Values = new double[] { 2 }},
new PieSeries<double> { Values = new double[] { 2 }},
new PieSeries<double> { Values = new double[] { 2 }},
};
Now I somehow need to first GroupBy bool and then select a new List? I have tried following:
IEnumerable<DataRecord> dataRecords = await this.DataStore.GetItemsAsync();
this.ActivityChartSeries = dataRecords
.GroupBy(g => g.AppIsRunning)
.Select(m => new
{ // BELOW IS TOTALLY UNCLEAR FOR ME
Values = m.Select(r => r.EngineElapsed.Ticks),
Name = m.Select(r => r.Name),
})
.Select(x =>
new PieSeries<double>
{
Values = new List<double> { x.Values.FirstOrDefault() },
Name = x.Name.FirstOrDefault(),
});
Type of assigned variable:
public IEnumerable<ISeries> ActivityChartSeries
This part is totally unclear for me:
Values = m.Select(r => r.EngineElapsed.Ticks),
Name = m.Select(r => r.Name),
How after GroupBy I can create two types of data? Basically I need
"Application Running" and "Values"
"Application is not Running" and "Values"
EDIT:
Code provided by Somar Zein compiles fine:
var results = activityChartSeries
.GroupBy(a=> a.AppIsRunning)
.Select(item=> new PieSeries<double>{
Name = item.Key ? "Application is Running" : "Application is not Running",
Values = item.Select(x=> Convert.ToDouble(x.ElapsedTime.Ticks)).ToList()
});
However as a result I am getting something like this, why it is reloading in a loop?
Here is result:
enter image description here
EDIT2:
So I have created an example for testing purposes:
Class:
public class DataModel
{
public int Id { get; set; }
public TimeSpan ElapsedTime { get; set; }
public bool AppIsRunning { get; set; }
}
Code:
List<DataModel> records = new List<DataModel>();
records.Add(new DataModel { Id = 1, ElapsedTime = new TimeSpan(1, 20, 30), AppIsRunning = true });
records.Add(new DataModel { Id = 2, ElapsedTime = new TimeSpan(1, 20, 30), AppIsRunning = true });
records.Add(new DataModel { Id = 3, ElapsedTime = new TimeSpan(1, 20, 30), AppIsRunning = true });
records.Add(new DataModel { Id = 4, ElapsedTime = new TimeSpan(1, 20, 30), AppIsRunning = true });
records.Add(new DataModel { Id = 5, ElapsedTime = new TimeSpan(1, 20, 30), AppIsRunning = true });
this.ActivityChartSeries = records
.GroupBy(g => g.AppIsRunning)
.Select(item => new PieSeries<double>
{
Name = item.Key ? "Running" : "Not Running",
Values = new double[] { 2, 4 },
});
I get the same reloading effect, even thou originally provided Example from LiveCharts work fine.
you could try doing something like following:
var results = activityChartSeries
.GroupBy(a=> a.AppIsRunning)
.Select(item=> new PieSeries<double>{
Name = item.Key ? "Application is Running" : "Application is not Running",
Values = item.Select(x=> Convert.ToDouble(x.ElapsedTime.Ticks)).ToList()
});
hope that could be helpful!

C# select duplicates from sub-group

I would like to filter out "" names then select each unique location where there are duplicate IDs regardless of name:
Data Setup
var list = new[]
{
new { id = 3, Name = "", Location = "LocationA" },
new { id = 2, Name = "", Location = "LocationA" },
new { id = 1, Name = "T", Location = "LocationB" },
new { id = 2, Name = "H", Location = "LocationB" },
new { id = 3, Name = "E", Location = "LocationB" },
new { id = 3, Name = "R", Location = "LocationB" },
new { id = 5, Name = "U", Location = "LocationC" },
new { id = 5, Name = "S", Location = "LocationC" },
new { id = 5, Name = "S", Location = "LocationD" },
new { id = 4, Name = "O", Location = "LocationD" },
new { id = 4, Name = "Z", Location = "LocationE" },
};
Query
var query1 = list
.Where(s => s.Name != "")
.GroupBy(g => g.Location)
.Where(w => w.Select(s => s.Location).Count() > 1)
.SelectMany(s => s)
.GroupBy(g => g.id)
.Where(w => w.Select(s => s.id).Count() > 1)
.SelectMany(s => s)
.ToList();
Console.WriteLine("output\n" + string.Join("\n", query1));
Returns
{ id = 3, Name = E, Location = LocationB }
{ id = 3, Name = R, Location = LocationB }
{ id = 5, Name = U, Location = LocationC }
{ id = 5, Name = S, Location = LocationC }
{ id = 5, Name = S, Location = LocationD }
vs What I actually wanted
{ id = 3, Name = E, Location = LocationB }
{ id = 3, Name = R, Location = LocationB }
{ id = 5, Name = U, Location = LocationC }
{ id = 5, Name = S, Location = LocationC }
LocationD has IDs 4 & 5 so it should've been filtered out, I wasn't able to do so. What am I doing wrong? How do I correct it?
Given
var list = new[]
{
new { id = 3, Name = "", Location = "LocationA" },
new { id = 2, Name = "", Location = "LocationA" },
new { id = 1, Name = "T", Location = "LocationB" },
new { id = 2, Name = "H", Location = "LocationB" },
new { id = 3, Name = "E", Location = "LocationB" },
new { id = 3, Name = "R", Location = "LocationB" },
new { id = 5, Name = "U", Location = "LocationC" },
new { id = 5, Name = "S", Location = "LocationC" },
new { id = 5, Name = "S", Location = "LocationD" },
new { id = 4, Name = "O", Location = "LocationD" },
new { id = 4, Name = "Z", Location = "LocationE" },
};
Example
var results = list
.Where(s => s.Name != "")
.GroupBy(x => new {x.id, x.Location})
.Where(g => g.Count() > 1)
.SelectMany(y => y);
foreach (var result in results)
Console.WriteLine($"{result.id}, {result.Name}, {result.Location}");
Output
3, E, LocationB
3, R, LocationB
5, U, LocationC
5, S, LocationC
Group by id and Location. And get .Count() more than 1.
var query1 = list
.Where(s => s.Name != "")
.GroupBy(g => new { g.Location, g.id })
.Where(g => g.Count() > 1)
.SelectMany(g => g)
.ToList();
Sample demo

Select the Most Recent Entry of Each Distinct Value in Linq

Given a list of values with an unknown number of distinct string values, how do I get the most recent value of Each?
I am given a list of objects with the following three properties: Balance, BalanceType, and CreatedDate. Going in, I know there are a number of distinct values BalanceType can be set to, but I cannot be sure how many distinct values there are. For example, this is a valid input:
[{
"BalanceType":"Cash",
"Balance":350.03,
"CreatedDate":10-20-16
},
{
"BalanceType":"Cash",
"Balance":250.01,
"CreatedDate":10-20-15
},
{
"BalanceType":"Cash",
"Balance":450.21,
"CreatedDate":10-20-14
},
{
"BalanceType":"Securiites",
"Balance":350.03,
"CreatedDate":10-20-16
}]
As is the following:
[{
"BalanceType":"Cash",
"Balance":350.03,
"CreatedDate":10-20-16
},
{
"BalanceType":"Credit",
"Balance":250.01,
"CreatedDate":10-20-15
},
{
"BalanceType":"LoanAmount",
"Balance":450.21,
"CreatedDate":10-20-14
},
{
"BalanceType":"Securiites",
"Balance":350.03,
"CreatedDate":10-20-16
}]
I have already tried using the Max function to do this, but I discovered it only gives the maximum indicated value, not the object. What am I missing?
This Question is related, but in mysql so it isn't usable for me.
It is helpful if you post data in C# format so it can be used directly. Translating your data, here are queries for your answer:
var src1 = new[] {
new {
BalanceType = "Cash",
Balance = 350.03,
CreatedDate = new DateTime(2016, 10, 20)
},
new {
BalanceType = "Cash",
Balance = 250.01,
CreatedDate = new DateTime(2015, 10, 20)
},
new {
BalanceType = "Cash",
Balance = 450.21,
CreatedDate = new DateTime(2014, 10, 20)
},
new {
BalanceType = "Securiites",
Balance = 350.03,
CreatedDate = new DateTime(2016, 10, 20)
}
};
var src2 = new[] {
new {
BalanceType = "Cash",
Balance = 350.03,
CreatedDate = new DateTime(2016, 10, 20)
},
new {
BalanceType = "Credit",
Balance = 250.01,
CreatedDate = new DateTime(2015, 10, 20)
},
new {
BalanceType = "LoanAmount",
Balance = 450.21,
CreatedDate = new DateTime(2014, 10, 20)
},
new {
BalanceType = "Securiites",
Balance = 350.03,
CreatedDate = new DateTime(2016, 10, 20)
}
};
var ans1 = from r in src1
group r by r.BalanceType into rg
let latest = rg.Max(r => r.CreatedDate)
select new { BalanceType = rg.Key, Balance = rg.Where(r => r.CreatedDate == latest).FirstOrDefault().Balance, CreatedDate = latest };
var ans2 = from r in src2
group r by r.BalanceType into rg
let latest = rg.Max(r => r.CreatedDate)
select new { BalanceType = rg.Key, Balance = rg.Where(r => r.CreatedDate == latest).FirstOrDefault().Balance, CreatedDate = latest };
I assumed that if there were more than one latest dated BalanceType, it didn't matter which was chosen, so I used the first. If your DateTimes actually had times you could possibly replace FirstOrDefault() with Single() and crash your program if your assumption is wrong.

Custom Sort in datagridview in winform

I have data table having rows like
ID Name
2 A
4 B
3 C
5 D
1 E
List order = new List() { "1", "3", "2", "5", "4" }
--------------order by list-----------------
ID Name
1 E
3 C
2 A
5 D
4 B
can anyone help to implement this.. I am using DataTable in Winforms.
Another solution to the already given ones, would be to loop your order list and then sort your source list.
// source list
List<Foo> lSource = new List<Foo>() {
new Foo() { ID = 2, Name = "A" },
new Foo() { ID = 4, Name = "B" },
new Foo() { ID = 3, Name = "C" },
new Foo() { ID = 5, Name = "D" },
new Foo() { ID = 1, Name = "E" },
};
// order list
List<int> order = new List<int>() { 1, 3, 2, 5, 4 };
// loop order list and sort source list
order.ForEach(x =>
{
lSource = lSource.OrderBy(g => g.ID == x).ToList();
});
// set datasource
dataGridView1.DataSource = lSource;
I just added a class Foo containing an int ID and a string Name, because you didn't share your whole code.
I think you can join your order and your datatable with AsEnumerable method and on on part you can equalize both of them and select rows, then you can generate a DataTable from that query with CopyToDataTable method.
var dt = new DataTable();
var dc = new DataColumn() { ColumnName = "ID", DataType = typeof(string) };
dt.Columns.Add(dc);
dc = new DataColumn() { ColumnName = "Name", DataType = typeof(string) };
dt.Columns.Add(dc);
dt.Rows.Add(new object[] { "2", "A" });
dt.Rows.Add(new object[] { "4", "B" });
dt.Rows.Add(new object[] { "3", "C" });
dt.Rows.Add(new object[] { "5", "D" });
dt.Rows.Add(new object[] { "1", "E" });
List<string> order = new List<string>() { "1", "3", "2", "5", "4" };
var query = from item in order
join row in dt.AsEnumerable() on item equals row.Field<string>("ID")
select row;
var result = query.CopyToDataTable();
result will be;
I'm not sure this is the best way or not but this seems to fit with your case.
You can join both lists (the one with items and the one with sorted id's) and then select the items:
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
var list = new List<Item>{
new Item { Id = 2, Text = "A" },
new Item { Id = 4, Text = "B" },
new Item { Id = 3, Text = "C" },
new Item { Id = 5, Text = "D" },
new Item { Id = 1, Text = "E" }
};
var sortorder = new List<int> { 1, 3, 2, 5, 4 };
var sortedlist = sortorder.Join(list, x => x, y => y.Id, (x,y) => y);
foreach(var item in sortedlist)
Console.WriteLine("{0} {1}", item.Id, item.Text);
}
}

C# combine to list in json object

I have two lists of string:
List<string> tmpCols = new List<string>();
List<string> tmpRows = new List<string>();
e.g. tmpCols = [A,B,C]; and tmpRows = [X, Y];
I need to iterate both list and get a Json result like this:
new matrix() { id = "1", col = "A", row = "X" });
new matrix() { id = "2", col = "B", row = "X" });
new matrix() { id = "3", col = "C", row = "X" });
new matrix() { id = "4", col = "A", row = "Y" });
new matrix() { id = "5", col = "B", row = "Y" });
new matrix() { id = "6", col = "C", row = "Y" });
The dimension in this case would be 2 rows and 3 columns.
This is a textbook example of a nested loop. Loops can contain other loops, where the inner one repeats for each element of the outer one. This one might look something like:
var result = new List<matrix>();
var count = 1;
foreach (var r in tmpRows)
foreach (var c in tmpCols)
result.Add(new matrix { id = (count++).ToString(), col = c, row = r });
I think this is a late answer
need to iterate both list and get a Json result like this:
It is not a json, I guess you want something like this
List<string> tmpCols = new List<string>() { "A", "B", "C" };
List<string> tmpRows = new List<string>() { "X", "Y" };
var query = tmpCols.SelectMany(c => tmpRows.Select(r => new {id=index++, col=c, row = r }));
var json = JsonConvert.SerializeObject(query, Newtonsoft.Json.Formatting.Indented);
Console.WriteLine(json);
OUTPUT:
[
{
"id": 6,
"col": "A",
"row": "X"
},
{
"id": 7,
"col": "A",
"row": "Y"
},
{
"id": 8,
"col": "B",
"row": "X"
},
{
"id": 9,
"col": "B",
"row": "Y"
},
{
"id": 10,
"col": "C",
"row": "X"
},
{
"id": 11,
"col": "C",
"row": "Y"
}
]
Solved using this code:
var tmpMatrix = new List<matrix>();
for (int k = 0; k < tmpRows.Count; k++)
{
for (int j = 0; j < tmpCols.Count; j++)
{
int ident = k*tmpCols.Count + j;
tmpMatrix.Add(new matrix() { id = ident.ToString(), col = tmpCols[j], row = tmpRows[k] });
}
}

Categories

Resources