I'm using NUnit 2.5.7. I want to test whether a collection of custom objects of a particular class contains certain objects, based on one of the class's properties.
e.g. a contrived example...
public class Person
{
public string Name { get; set; }
public Person(string name)
{
Name = name;
}
}
// ...
public List<Person> GetFavouritePeople()
{
List<Person> favouritePeople = new List<Person>();
favouritePeople.Add(new Person("joe"));
favouritePeople.Add(new Person("fred"));
favouritePeople.Add(new Person("jenny"));
return favouritePeople;
}
// ...
[Test]
public GetFavouritePeople()
{
List<Person> people = GetFavouritePeople();
// What I'd like to test, but not sure how to do it...
Assert.Contains(Name="joe", people);
Assert.Contains(Name="fred", people);
Assert.Contains(Name="jenny", people);
}
Although it would be simple enough in this example, I don't want to create mock objects for each Person and use those in the assertion... I just want to check based on a particular property (Name in this example.)
You could use LINQ:
Assert.That(people.Any(p => p.Name == "joe"));
or, if you want to be explicit about there being exactly one person with each name:
Assert.That(people.Count(p => p.Name == "joe"), Is.EqualTo(1));
If you want a better error message than "Assertion failed, expected true, was false", you could create your own assert method.
For several collection-related asserts, CollectionAssert is very useful - for instance, it allows you to check if two collections contain the same elements, irrespective of their order. So yet another possibility is:
CollectionAssert.AreEquivalent(new[] {"joe", "fred", "jenny"}, people.Select(p => p.Name).ToList());
Note that CollectionAssert.AreEquivalent() is a little picky with regard to the types it accepts (even though the signature takes IEnumerable). I usually wrap it in another method that calls ToList() on both parameters before invoking CollectionAssert.AreEquivalent().
You can use Assert.That in conjunction with Has.Exactly(1).Matches:
List<Person> people = GetFavouritePeople()
Assert.That(people, Has.Exactly(1).Matches<Person>(p => p.Name == "NUnit is amazing")));
Failure message will be along lines of:
Expected: exactly one item value matching lambda expression
But was: 0 items < [result of people.ToString()] >
You can use Linq's Intersect() to determine whether all the expected items are within the list your testing against even if the list contains other items that you are not testing for:
[Test]
public void TestFavouritePeople()
{
var people = GetFavouritePeople();
var names = people.Select(p => p.Name);
var expectedNames = new[] {"joe", "fred", "jenny"};
var actualNames = names.Intersect(expectedNames);
CollectionAssert.AreEquivalent(expectedNames, actualNames);
}
For NUnit 3.0 and greater, you can use Is.SupersetOf():
[Test]
public void TestFavouritePeople()
{
var people = GetFavouritePeople();
var names = people.Select(p => p.Name);
var expectedNames = new[] {"joe", "fred", "jienny"};
var actualNames = names;
Assert.That(actualNames, Is.SupersetOf(expectedNames));
}
Related
Is there any way to return a string parameter and a list to the method in c#?
List<cCountry> countries = new List<cCountry>();
countries = GetCountries(userProfile.Country);
private List<cCountry> GetCountries(string p)
{
inputCollection = new cDTOCollection<cDTOBase>();
outputCollection = new cDTOCollection<cDTOBase>();
outputCollection = UpdateProfileBizobj.ProcessRequest(ActionConstants.ActionGetCountriesList, null);
List<cCountry> countries = new List<cCountry>();
cDTOSingleValue SelectedCountryID = new cDTOSingleValue();
foreach (cDTOCountry countryItem in outputCollection)
{
if (p == countryItem.CountryName)
SelectedCountryID.Id = countryItem.CountryID;
countries.Add(Mapper.Map<cDTOCountry, cCountry>(countryItem));
}
countries.Remove(countries[0]);
return countries;
}
Like in the method above I need to return a parameter
SelectedCountryID and also the countries list.Is there any way to
return both?
populate and return an object instead.
public class ReturnObject
{
public List<cCountry> Countries { get; set; }
public guid SelectedCountryID { get; set; } // don't think you defined what type SelectedCountryID is in your question
}
But if you find yourself needing to return more than 1 thing, it's probably an indication that your method is doing too much and should be refactored.
Why can't you reuse the value that you are sending to the method?
return Tuple.Create(new List<Country>(),"astring")
Answer to your question
You can also use the out modifier on a parameter to pass by reference, which would let the method modify the resulting object, effectively returning it. That's a pretty bad design for most cases though, and you probably refactor your methods into smaller pieces or wrap things up into better objects.
In your code:
private List<cCountry> GetCountries(string p, out cDTOSingleValue SelectedCountryID)
{
//your code
}
Potential Refactoring
Looking at your code it, seems your really are trying to do two separate things.
Getting Countries and mapping them
Finding the last country whose name matches the parameter passed in
So as long as your country list isn't ridiculously large, making two separate method calls will make your code more readable and more maintainable. I like using LINQ to manipulate the in-memory collections.
I'd personally use one method to fetch the data.
private List<cDTOCountry> GetCountries()
{
inputCollection = new cDTOCollection<cDTOBase>();
outputCollection = new cDTOCollection<cDTOBase>();
return UpdateProfileBizobj.ProcessRequest(ActionConstants.ActionGetCountriesList, null);
}
And then later I'd process the data as needed:
var preMappedCountries = GetCountries();
var mappedCountries = preMappedCountries
.Select(c => Mapper.Map<cDTOCountry, cCountry>(c)) //map the data
.Skip(1) //skip the first element (the remove index 0)
.ToList(); //cast to List. Read more on LINQ's deferred execution.
var lastMatchingName = preMappedCountries
.LastOrDefault(c => c.Name == p); //gets the last country with matching name
The benefit to separating the logic into pieces is potential reuse of methods. If you ever find yourself needing to get data without mapping, you can do just that and skip all the LINQ logic. This way the logic that gets data is distinct from the logic that matches country names.
In your case an out param seems more appropriate. Otherwise as Kevin suggested you can return a Tuple.
I want to be able to use one particular query in several other functions, I have a class that just creates a specialized QueryOver object for a particular domain.
But that function uses alias objects to create the joins. How can I access those aliases from another function?
For example say I have Course entities that each have a collection of students.
And I always want to only get Active ( a bool value) courses
public class QueryHelperClass
{
public QueryOver<Course, Course> GetQuery()
{
Address studentAlias = null;
QueryOver<Course, Course> query = QueryOver.Of<Course>(() => courseAlias)
.JoinAlias(x => cus.Student, () => studentAlias)
.Where(x => courseAlias.IsActive);
return query;
}
}
That works fine if all I need to do is GetExecutableQuery and return the results, but what do I do if I need to modify the query by accessing studentAlias?
Example:
public class SomeOtherClass
{
public List<Course> GetActiveCourseSummary(QueryOver<Course, Course> queryOver)
{
var query = queryOver.Where(a=> studentAlias.Name = "Bob");
...
}
}
From the SomeOtherClass.GetActiveCourseSummary I want to modify the query to only get courses where "Bob" is enrolled. But I can't access the studentAlias because it was defined in another function.
What can I do here, or am I setting this up all completely hard-core incorrectly?
In fact, we can re-declare the same variable in SomeOtherClass.
public List<Course> GetActiveCourseSummary(QueryOver<Course, Course> queryOver)
{
Address studentAlias = null;
var query = queryOver.Where(() => studentAlias.Name == "Bob");
...
}
The point is, that the name studentAlias (of the local variable Address) is the same as in the method GetQuery().
This will work, because what we pass in the .Where() method is the Expression. It is parsed and its string part "studentAlias" is used the same way as before, in GetQuery().
BUT
I would say, that this is not the way I would use. It is not clear what is passed into SomeOtherClass, how the query was built. There already could be an alias, but also it could be just a simple QueryOver<Course, Course> queryOver.
My approach is to do it different way. Collect all restrictions all the way down. Once there is e.g. set of restrictions IList<ICriterion>, call the DAO method, create query and append these restrictions at one place. But it is different story
If we would like to get some more checks into SomeOtherClass: we can use the Criteria API. Down side is that we have to usestring representation of properties "Student" and "Code" (not so clean as QueryOver API)
public List<Course> GetActiveCourseSummary(QueryOver<Course, Course> queryOver)
{
var criteria = query.UnderlyingCriteria;
var rootAlias = criteria.Alias; // will return "courseAlias"
var path = rootAlias + ".Student"; // the path
var student = criteria.GetCriteriaByPath(path)
?? criteria.CreateCriteria(path, path);
var studentAlias = student.Alias; // finally we do have existing alias
queryOver.And(Restrictions.Eq(studentAlias + ".Name ", "Bob"));
...
How can one go about sharing query logic between LINQ and Rx? i.e., if I need to sometimes query against an IObservable stream and sometimes against an IEnumerable, but the exact same logic is in each, is there any way to share that logic?
Maybe an example will help. In the following Queries class, I want to combine the sequence of people and purchases to produce a "notice" string. Notice I have to duplicate the exact same logic; all that's different is that one is IEnumerable and one is IObservable. Is there any way of consolidating these two functions? I've tried using various combinations of ToObservable and ToEnumerable, but everything I've tried seems to either hang or produce no result.
(Higher-kinded question: Is this the exact thing that the idea of higher-kinded types was created to solve? i.e., would this not even be a problem in Haskell or Scala?)
static class Queries {
static IObservable<string> GetPurchaseNotices(IObservable<Person> people, IObservable<Purchase> purchases) {
return from person in people
from purchase in purchases
where person.Id == purchase.PurchaserId
select person.Name + " purchased a " + purchase.ItemName;
}
static IEnumerable<string> GetPurchaseNotices(IEnumerable<Person> people, IEnumerable<Purchase> purchases) {
return from person in people
from purchase in purchases
where person.Id == purchase.PurchaserId
select person.Name + " purchased a " + purchase.ItemName;
}
}
class Person {
public Person(int id, string name) {
Id = id;
Name = name;
}
public string Name;
public int Id;
}
class Purchase {
public Purchase(int purchaserId, string itemName) {
PurchaserId = purchaserId;
ItemName = itemName;
}
public int PurchaserId;
public string ItemName;
}
As far as I know, this is not possible in C# (or F#) directly. The problem is that while you can abstract over the generic argument T in IEnumerable<T> or IObservable<T>, you cannot abstract over the "kind" IEnumerable or IObservable.
With higher-kinded types, like those in Haskell or Scala, you could express this given a suitable interface for IEnumerble and IObservable. In Haskell, it would look something like:
getPurchases :: MonadPlus m => m Person -> m Purchaser -> m String
getPurchases people purchases = do
person <- people
purchase <- purchases
if (personId person) == (purchaserId purchase)
then return $ (name person) ++ "purchased a " ++ (itemName purchase)
else mzero
which you could then use for both IEnumerable and IObservable.
I don't know whether IObservable actually satisfies the required laws for MonadPlus however, so this is just an example.
Switching from observable to enumerable is not a good idea since the enumerable will block, so it will be less problematic the other way around. You should be able to use a single function that filters an IObservable<Person>.
Here's simple program that demonstrates the idea. Notice it uses a single method for filtering IObservable<int>. In case of IEnumerable<int>, it switches ToObservable before calling the method, and then switches back ToEnumerable after getting the result.
static void Main(string[] args)
{
var observableNums = Observable.Interval(TimeSpan.FromSeconds(1))
.Select(x => (int)x);
var observableOdds = FilterOdds(observableNums);
observableOdds.Subscribe(Console.WriteLine);
var enumerableNums = new[] { 1, 2, 3, 4, 5, 6 };
var enumerableOdds = FilterOdds(enumerableNums.ToObservable());
foreach (var i in enumerableOdds.ToEnumerable())
Console.WriteLine(i);
Console.ReadKey();
}
static IObservable<int> FilterOdds(IObservable<int> nums)
{
return nums.Where(i => i % 2 == 1);
}
I found this post Match elements between 2 collections with Linq in c# which explained how you can use Intersect to find matching elements between two lists.
Can you use this to match elements in two lists that are not of exactly the same, but have "sub values" that you want to match?
My example is this: I have two collections, each containing lists of XElements. The one with elements called <link> and the other with elements called <file>, each have attributes called "path", and it is this attribute I want to match. If the path attribute is equal, I want a match.
In the result set I would like a list of all the elements whose paths match the paths of the elements.
How can this be done?
I would suggest to use LambdaComparer which can be passed into the Intersect() method as Equality Comparer, it allows specifying comparison logic in place by providing boolean condition instead introducing a new comparer class each time, so your code would be clear enough:
firstCollection.Intersect(
secondCollection,
new LambdaComparer<YourClass>(
(item1, item2) => item1.PropertyName == item2.PropertyName));
// Below are lists and User class which demonstrates LambdaComparer and Intersect()
public class User
{
public string Name { get; set; }
}
IList<User> list1 = new List<User>
{
new User {Name = "A"},
new User { Name = "B"}
};
List<User> list2 = new List<User>
{
new User {Name = "C"},
new User { Name = "B"}
};
var resultSet = list1.Intersect<User>(
list2,
new LambdaComparer<User>((item1, item2) => item1.Name == item2.Name));
Basically if you need to compare cusotm attributes, you still can encapsulate this logic into
Func<User, User, bool> userNameComparer = (user1, user2) =>
{
// check attributes using user1.GetType().GetCustomAttributes()
};
And then use this comparer funciton as:
var resultSet = list1.Intersect<User>(
list2,
new LambdaComparer<User>((item1, item2) => userNameComparer));
EDIT: Note ragarding particular impelemntaion referenced in this answer
There is could be a problem that by default for hash funciton is hardcoded 0
6 public LambdaComparer(Func<T, T, bool> lambdaComparer) :
7 this(lambdaComparer, o => 0)
8 {
9 }
This can lead to performance issues in some cases so I would recommend to refactor it as:
public LambdaComparer(Func<T, T, bool> lambdaComparer) :
this(lambdaComparer,
EqualityComparer<T>.Default.GetHashCode(o))
{
}
So it wil use built in GetHashCode() implementation
This question already has answers here:
What is a Predicate Delegate and where should it be used?
(10 answers)
Closed 8 years ago.
I am very new to using predicates and just learned how to write:
Predicate<int> pre = delegate(int a){ a %2 == 0 };
What will the predicate return, and how is it useful when programming?
Predicate<T> is a functional construct providing a convenient way of basically testing if something is true of a given T object.
For example suppose I have a class:
class Person {
public string Name { get; set; }
public int Age { get; set; }
}
Now let's say I have a List<Person> people and I want to know if there's anyone named Oscar in the list.
Without using a Predicate<Person> (or Linq, or any of that fancy stuff), I could always accomplish this by doing the following:
Person oscar = null;
foreach (Person person in people) {
if (person.Name == "Oscar") {
oscar = person;
break;
}
}
if (oscar != null) {
// Oscar exists!
}
This is fine, but then let's say I want to check if there's a person named "Ruth"? Or a person whose age is 17?
Using a Predicate<Person>, I can find these things using a LOT less code:
Predicate<Person> oscarFinder = (Person p) => { return p.Name == "Oscar"; };
Predicate<Person> ruthFinder = (Person p) => { return p.Name == "Ruth"; };
Predicate<Person> seventeenYearOldFinder = (Person p) => { return p.Age == 17; };
Person oscar = people.Find(oscarFinder);
Person ruth = people.Find(ruthFinder);
Person seventeenYearOld = people.Find(seventeenYearOldFinder);
Notice I said a lot less code, not a lot faster. A common misconception developers have is that if something takes one line, it must perform better than something that takes ten lines. But behind the scenes, the Find method, which takes a Predicate<T>, is just enumerating after all. The same is true for a lot of Linq's functionality.
So let's take a look at the specific code in your question:
Predicate<int> pre = delegate(int a){ return a % 2 == 0; };
Here we have a Predicate<int> pre that takes an int a and returns a % 2 == 0. This is essentially testing for an even number. What that means is:
pre(1) == false;
pre(2) == true;
And so on. This also means, if you have a List<int> ints and you want to find the first even number, you can just do this:
int firstEven = ints.Find(pre);
Of course, as with any other type that you can use in code, it's a good idea to give your variables descriptive names; so I would advise changing the above pre to something like evenFinder or isEven -- something along those lines. Then the above code is a lot clearer:
int firstEven = ints.Find(evenFinder);
The Predicate will always return a boolean, by definition.
Predicate<T> is basically identical to Func<T,bool>.
Predicates are very useful in programming. They are often used to allow you to provide logic at runtime, that can be as simple or as complicated as necessary.
For example, WPF uses a Predicate<T> as input for Filtering of a ListView's ICollectionView. This lets you write logic that can return a boolean determining whether a specific element should be included in the final view. The logic can be very simple (just return a boolean on the object) or very complex, all up to you.
The following code can help you to understand some real world use of predicates (Combined with named iterators).
namespace Predicate
{
class Person
{
public int Age { get; set; }
}
class Program
{
static void Main(string[] args)
{
foreach (Person person in OlderThan(18))
{
Console.WriteLine(person.Age);
}
}
static IEnumerable<Person> OlderThan(int age)
{
Predicate<Person> isOld = x => x.Age > age;
Person[] persons = { new Person { Age = 10 }, new Person { Age = 20 }, new Person { Age = 19 } };
foreach (Person person in persons)
if (isOld(person)) yield return person;
}
}
}
In C# Predicates are simply delegates that return booleans. They're useful (in my experience) when you're searching through a collection of objects and want something specific.
I've recently run into them in using 3rd party web controls (like treeviews) so when I need to find a node within a tree, I use the .Find() method and pass a predicate that will return the specific node I'm looking for. In your example, if 'a' mod 2 is 0, the delegate will return true. Granted, when I'm looking for a node in a treeview, I compare it's name, text and value properties for a match. When the delegate finds a match, it returns the specific node I was looking for.