One of my common Class methods generates a list of parameters and I want to set each of them consistently as a parameter to my NUnit test.
I read some documentation about TestCaseSource attribute but can't figure out how to implement it.
For example my method return a list with
"1","2","3","4"
...inside how do I put each of them into my test. Thanks!
Here is my method that return a list:
public static List<string> TestCombinationsProvider()
{
List<string> resultList = new List<string>();
List<string> parametersList = new List<string>();
foreach (var item in ReturnDynamicPararmetersEntityProperties())
{
parametersList.Add(item.Name);
}
for (int i = 0; i < parametersList.Count; i++)
{
for (int j = i + 1; j < parametersList.Count; j++)
{
resultList.Add(parametersList[i] + " AND " + parametersList[j]);
}
}
return resultList;
}
And empty Nunit test:
[Test]
[TestCaseSource("")]
public void Test1()
{
}
I want to run my test with each row from my list
TestCaseSourceAttribute constructor has two overloads if you need to set data from another class you should use this constructor.
TestCaseSourceAttribute(Type sourceType, string sourceName);
And it looks like this:
public class TestData {
public static IEnumerable<string> TestCombinationsProvider()
{
var parametersList = ReturnDynamicPararmetersEntityProperties().Select(x => x.Name).ToList();
for (int i = 0; i < parametersList.Count; i++)
{
for (int j = i + 1; j < parametersList.Count; j++)
{
yield return parametersList[i] + " AND " + parametersList[j];
}
}
}
}
public class Tests
{
[TestCaseSource(typeof(TestData), nameof(TestData.TestCombinationsProvider))]
public void Test1(string test)
{
Assert.Pass();
}
}
The docs are pretty clear. Instead of returning a List<string>, you need to return a list of testcases, e.g. by directly using IEnumerable<TestCaseData>:
public static IEnumerable<TestCaseData> TestCombinationsProvider()
{
List<string> resultList = new List<string>();
List<string> parametersList = new List<string>();
foreach (var item in ReturnDynamicPararmetersEntityProperties())
{
parametersList.Add(item.Name);
}
for (int i = 0; i < parametersList.Count; i++)
{
for (int j = i + 1; j < parametersList.Count; j++)
{
yield return new TestCaseData(parametersList[i] + " AND " + parametersList[j]);
}
}
}
There are multiple different signatures for that method, e.g. also returning a collection of object[]. But I won´t recommend them, as you´re losing much of the things you can do with the TestCaseData, e.g. setting each tests Name or also its Description.
Then decorate your actuall test-method:
[Test]
[TestCaseSource(nameof(TestCombinationsProvider))]
public void Test1(string p)
{
}
EDIT: When your TestCombinationsProvider-method is in another class use this instead:
[TestCaseSource(typeof(TheClass), nameof(TheClass.TestCombinationsProvider))]
Related
I'm pretty new with C# and I'm stuck on one university exercise. I have to sort some elements and them display them by overriden method ToString. And override is problem there. List works with ToString, List of Lists not.
Untill now I've tried to create some easy foreach and put it into overriden method, still, without success. It works only out of method. Asked my professor and he told me, it's because I'm acessing List, not Lista1, or something like that. Like I've said, I'm newbie.
using System;
using System.Collections.Generic;
namespace lista_7
{
class Lista
{
public static Random rand = new Random();
public List<int> nums = new List<int> ();
public Lista(int n)
{
for (int i = 0; i <= n; i++)
{
nums.Add(rand.Next(100));
}
}
public Lista()
{
Random rand = new Random();
for (int i = 0; i <= rand.Next(5); i++)
{
nums.Add(rand.Next(100));
}
}
public override string ToString()
{
String result = "";
foreach (var numbers in nums)
{
result += numbers + " ";
}
return result;
}
}
class Lista1 : Lista, IComparable<Lista1>
{
public Lista1(int n) : base(n) { }
public Lista1() : base() { }
public int CompareTo(Lista1 x)
{
if (x == this) return 0;
else if (x == null) return 1;
for (int i = 0; i < this.nums.Count && i < x.nums.Count; i++)
{
if (this.nums[i] > x.nums[i]) return 1;
else if (this.nums[i] < x.nums[i]) return -1;
}
return x.nums.Count > this.nums.Count ? -1 : 1;
}
}
class Program
{
static void Main(string[] args)
{
List<Lista1> fir = new List<Lista1> {
new Lista1(5),
new Lista1(),
new Lista1(3)
};
foreach (var variable in fir)
{
//Console.Write ( toString )
foreach (var x in variable.nums)
{
Console.Write(x + " ");
}
Console.WriteLine();
}
Console.WriteLine(fir.ToString());
Console.ReadLine();
}
}
}
I would describe errors, but I dont have any. fir.ToString shows System.Collections.Generic.List`1[lista_7.Lista1]
Put your fir.ToString() inside your loop as variable.ToString():
foreach (var variable in fir)
{
Console.WriteLine(variable.ToString());
}
I'm not sure it's a good idea to override ToString() method, I'd rather create an extension method for this, but that's about how it should work.
From the comments, he's requiring you to inherit from a list and override its ToString() method, and then inherit from a list of that list and override its ToString() method.
First, the inner list (for lack of a better term):
public class InnerList : List<int>
{
public override string ToString()
{
// return the contents of the list somehow formatted as strings.
return string.Join(" ", this);
}
}
Next, a list of that list:
public class OuterList : List<InnerList>
{
public override string ToString()
{
var result = new StringBuilder();
ForEach(inner =>
{
if (inner != null) result.AppendLine(inner.ToString());
});
return result.ToString();
}
}
The ToString() method of the outer list works by calling the ToString() method of all of the lists it contains.
I'm obviously making up what goes in the overridden methods. But this is how you would override them according to the requirements you specified. In "real life" this wouldn't make any sense. We might declare a List<List<int>> without creating any new classes, and then write code to render it as a string. We could write code to render the same List<List<int>> two different ways. If we do this by overriding ToString() it suggests that we would create different inherited classes to format the numbers differently.
(Some courses tend to over-emphasize inheritance. It's useful, but they make it seem like it's the answer to everything.)
Note that there's also no need for either list to populate itself. That just makes it more confusing. You can write separate code to add numbers to it.
I'm trying to create a CRUD menu that allows me to insert data at an array and also search it by id.
However I'm trying to create a method that allow to check if id exists and after to display the output.
The problem is that the method isn't correct enough for me to display it across other methods, and also at a switch statement. The problem is it repeats two times in row what is the Id you want to check.
Here's the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace menu
{
class Program
{
private static int id = 1;
enum dataInsert { ID, NAME, SURNAME, ADDRES };
static void Main(string[] args)
{
string[,] matrix = new string[10, 4];
insertData(matrix);
searchId(matrix);
visualizeByid(matrix);
}
static int generateId()
{
return id++;
}
static void insertData(string[,] matrix)
{
int n = generateId();
for (int j = 1; j < matrix.GetLength(1); j++)
{
matrix[n - 1, 0] = Convert.ToString(n);
Console.Write($"Insert {Enum.GetName(typeof(dataInsert), j)}: ");
matrix[n - 1, j] = Console.ReadLine();
}
}
static int searchId(string[,] matrix)
{
int choosenId, index = -1;
do
{
Console.Write("Insert Id to visualize: ");
} while (!int.TryParse(Console.ReadLine(), out choosenId));
for (int i = 0; i < matrix.GetLength(0); i++)
{
if (Convert.ToString(choosenId) == matrix[i, 0])
{
index = i;
}
}
return index;
}
static void visualizeByid(string[,] matrix)
{
int pos = searchId(matrix);
for (int i = pos; i < pos + 1; i++)
{
for (int j = 0; j < matrix.GetLength(1); j++)
{
Console.Write($"{matrix[i, j]}\t");
}
Console.WriteLine();
}
}
}
}
The reason "Insert Id to visualize: " is displayed twice is because your program is calling static int searchId(string[,] matrix) twice in a row:
In Main
static void Main(string[] args)
{
string[,] matrix = new string[10, 4];
insertData(matrix);
searchId(matrix); //Here
visualizeByid(matrix); //Called immediately after
}
And visualizeByid
static void visualizeByid(string[,] matrix)
{
int pos = searchId(matrix); //Here
...
}
You should be able to get your expected result by removing the call to searchId from Main.
Unless I'm misunderstanding, it looks like you have an array of objects. Even if those are simply a name and id.
public class Obj
{
public int Id { get; set; }
public string Name { get; set; }
}
Then you have an array, although you could also use a list.
List<Obj> Objects = new List<Obj>();
To check the list/array by Id you can simply use Linq
if (Objects.Where(o => o.Id == IdToCheck).Count() == 0)
{
//Insert new object
Objects.Add(NewObject);
}
Ok, so in a console application I'm working on, I have a list (myList) in Class01
class Class01
{
public List<string> myList = new List<string>();
public void _addsList()
{
myList.Add("0001Test01");
myList.Add("0002Test02");
myList.Add("0003Test03");
myList.Add("0004Test04");
for (int i = 0; i < myList.Count; i++)
{
Console.WriteLine(myList[i] + ",");
}
}
}
and I need to read that list in Class02
class Class02
{
public void _callList()
{
var class02 = new Class01();
string wits2;
List<string> buffer = new List<string>();
for (int i = 0; i < class02.myList.Count; i++)
{
wits2 = class02.myList[i].Substring(0, 4);
Console.WriteLine(class02.myList[i]);
}
Console.ReadKey();
}
}
The Output of this program should write this to the Console:
0001Test01,
0002Test02,
0003Test03,
0004Test04,
0001
0002
0003
0004
Now I've seen GetList used to do this
public class MyClass {
private List<string> myList = new List<string>();
public List<string> GetList()
{
return myList;
}
}
public class CallingClass {
MyClass myClass = new MyClass();
public void GetList()
{
List<string> calledList = myClass.GetList();
///More code here...
}
}
But I for the life of me can not get this to work. I don't know if I'm missing a namespace or what. I don't even know if GetList works in console application.
So I would really appreciate the help.
Thanks-
Though not totally clear from your question what is not working. But I suspect you need to put values in the list. If you mean it is not displaying anything in the console try this:
var class02 = new Class01();
string wits2;
class02._addsList();
EDIT: after reading your comment, I think this will remedy it:
for (int i = 0; i < class02.myList.Count; i++)
{
wits2 = class02.myList[i].Substring(0, 4);
Console.WriteLine(class02.myList[i]);
buffer.Add(wits2);//Add it to list declared in this function
}
NOTE: If you mean you are getting output when calling _addsList on class object the make sure that you have called this function once before using an object of Class01. From second block of code for Class02 you are not calling _addsList function on object of Class01.
On your Class02:
var class02 = new Class01();
class02._addsList(); //Add this on your declaration
string wits2;
Then change the variable you are passing on your Console.WriteLine:
List<string> buffer = new List<string>();
for (int i = 0; i < class02.myList.Count; i++)
{
wits2 = class02.myList[i].Substring(0, 4);
//Console.WriteLine(class02.myList[i]); //Remove this
Console.WriteLine(wits2); //Use wits2 instead since this is what you get on your Substring
}
I think most important thing you are missing is that your classes are not marked as public
so please add public before class declarations as below
public class Class02
{
......
One more thing, to get your required output, in your class02 you are assigning substring to 'wits' variable but not printing it. You are instead passing value from list to Console.Writeline.
Hope this helps
Thanks to TheVillageIdiot. I got this working now. So thank you. My code looks like this now:
public class Class01
{
public List<string> myList = new List<string>();
public void _addsList()
{
myList.Add("0001Test01");
myList.Add("0002Test02");
myList.Add("0003Test03");
myList.Add("0004Test04");
}
}
class Class02
{
public void _callList()
{
var class01 = new Class01();
class01._addsList(); //<--- Had to add this line
for (int i = 0; i < class01.myList.Count; i++)
{
Console.WriteLine(class01.myList[i] + ",");
}
string wits2;
List<string> buffer = new List<string>();
for (int i = 0; i < class01.myList.Count; i++)
{
wits2 = class01.myList[i].Substring(0, 4);
Console.WriteLine(wits2);
}
Console.ReadKey();
}
}
For toughs who didn't understand the problem, Class02 could not read the List in Class01.
Thanks for the Help!
I am trying to understand closures, already read some materials but.. then i tried this.
As far as i understand, a class is generated containing the specific anonymous method (in my case, the one writing to the console) and the int variable j. How does it store all the j values in only one class? Are there many instances of this kind of class generated behind the scenes?
class Program
{
public static List<Action> actions = new List<Action>();
static void Main(string[] args)
{
AddActions(10);
actions[0]();
actions[1]();
Console.ReadLine();
}
public static void AddActions(int count)
{
for (int i = 0; i < count; i++)
{
int j = i;
actions.Add(delegate()
{
Console.Write("{0} ", j);
});
}
}
}
with result: 0 1
Here is your code decompiled into classes rather than lambdas.
private class Program
{
public static List<Action> actions;
static Program()
{
Program.actions = new List<Action>();
}
private static void Main(string[] args)
{
Program.AddActions(10);
Program.actions[0]();
Program.actions[1]();
Console.ReadLine();
}
public static void AddActions(int count)
{
for (int index = 0; index < count; ++index)
{
Program.\u003C\u003Ec__DisplayClass2_0 cDisplayClass20 = new Program.\u003C\u003Ec__DisplayClass2_0();
cDisplayClass20.j = index;
Program.actions.Add(new Action((object)cDisplayClass20, __methodptr(\u003CAddActions\u003Eb__0)));
}
}
private sealed class \u003C\u003Ec__DisplayClass2_0
{
public int j;
public \u003C\u003Ec__DisplayClass2_0()
{
base.\u002Ector();
}
internal void \u003CAddActions\u003Eb__0()
{
Console.Write("{0} ", (object)this.j);
}
}
}
As you can see, for example iteration of the loop you get a new instance of new Program.\u003C\u003Ec__DisplayClass2_0();.
Yes, many instances are generated.
You need an the extra variable j in the scope of the loop body because the variable i has a scope of the method's body, and only a single closure object would be generated for it.
void Main()
{
AddActions(10);
var closure1 = functions[0]();
var closure2 = functions[1]();
Console.WriteLine(object.ReferenceEquals(closure1, closure2));
// False
}
public static void AddActions(int count)
{
for (int i = 0; i < count; i++)
{
int j = i;
functions.Add(delegate()
{
Console.WriteLine(j);
Expression<Func<int>> exp = () => j;
Console.WriteLine(exp.ToString());
var m = (MemberExpression)exp.Body;
var c = (ConstantExpression)m.Expression;
Console.WriteLine(c.Value.ToString());
return c.Value;
});
}
}
public static List<Func<object>> functions = new List<Func<object>>();
Result
0
() => value(UserQuery+<>c__DisplayClass1_0).j
UserQuery+<>c__DisplayClass1_0
1
() => value(UserQuery+<>c__DisplayClass1_0).j
UserQuery+<>c__DisplayClass1_0
False
Here is my array of objects
Game[] gameConsoles = new Games[5];
// paramaters are name of the console and game ID
gameConsoles[0] = new Games("Playstation 4", 101);
gameConsoles[1] = new Games("Xbox 1", 108);
gameConsoles[2] = new Games("PS Vita", 110);
gameConsoles[3] = new Games("Wii U", 104);
gameConsoles[4] = new Games("3DS", 102);
for (int i = 0; i < gameConsoles.Length; i++)
{
gameConsoles[i].display();
}
It will basically display all 5 objects in each message box but how do I make it so that it can display them based on the game ID order in ascending?
My sorting algorithm I used when I sorted a regular array of numbers.
public void ascendingOrder()
{
// helper class
double temp = 0;
for (int j = 0; j < numbers.Length; j++)
{
for (int i = 0; i < numbers.Length - 1; i++)
{
if (numbers[i] > numbers[i + 1])
{
temp = numbers[i];
numbers[i] = numbers[i + 1];
numbers[i + 1] = temp;
}
}
}
}
You can use use LINQ OrderBy.
foreach(var item in gameConsole.OrderBy(r=> r.GameID))
{
item.display();
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
SortedDictionary<int, Game> gameConsoles = new SortedDictionary<int, Game>();
gameConsoles.Add(101, new Game("Playstation 4", 101));
gameConsoles.Add(108, new Game("Xbox 1", 108));
gameConsoles.Add(110, new Game("PS Vita", 110));
gameConsoles.Add(104, new Game("Wii U", 104));
gameConsoles.Add(102, new Game("3DS", 102));
foreach (KeyValuePair<int, Game> item in gameConsoles)
{
Console.WriteLine(item.Value.ToString());
}
Console.ReadKey();
}
}
public class Game
{
public Game(string name, int id)
{
Id = id;
Name = name;
}
public int Id { get; set; }
public string Name { get; set; }
public override string ToString()
{
return string.Format("Id: {0} Name: {1}", Id, Name);
}
}
}
There are three common ways to order items in .NET:
Using LINQ (your comments suggest that this is not allowed for the purposes of your assignment)
Implementing IComparable<Games> in your Games class, or
Providing an instance of IComparer<Games> to the Sort method.
Here is how you implement IComparable<Games>:
class Games : IComparable<Games> {
public int CompareTo(Games other) {
return GameId.CompareTo(other.GameId);
}
}
Now your Games would sort based on GameId.
Here is how you use an external IComparer<Games>:
class CompareGamesOnId : IComparer<Games> {
int Compare(Games a, Games b) {
return a.GameId.CompareTo(b.GameId);
}
}
You call Sort like this:
Array.Sort(games, new CompareGamesOnId());
You could use a 1 liner for this. LINQ is good for operations which do not affect the set.
gameConsoles.OrderBy(gc => gc.GameID).ToList().ForEach(g => g.display());
Implement IComparable on Games and use the .Sort method?IComparable
You can try LINQ without using the dreaded => symbol, although of course, it is not recommended for simplicity purposes. However, this explains what exactly is => doing,
foreach (var item in gameConsole.OrderBy(delegate(Game g) { return g.GameId; }))
{
item.display();
}