FluentAssertions: Assert all object properties are different from another object - c#

Is there any way to assert that all properties of objectA are different from all properties of objectB using FluentAssertions? objectA and objectB are instances of the same class.
.BeEquivalentTo() checks if any of the property is different. I'm looking for the same check that passes only if both objects have no equal properties and fails if at least one property is the same.

Unfortunately not. I recommend requesting an improvement at https://github.com/fluentassertions/fluentassertions/issues

Related

Are C# properties objects?

I'm learning C# from the book "Head First C#". I thought I understood properties. They are used like fields but work like methods, with getters and setters. I never thought of them as another object appending to the instantiated object. Is that the case?
Please see the code given in the book and the Outfit object which got me thinking about this.
Thank you so much for your help!!
Follow-up questions:
Is it the case that when an object is instantiated, all of its properties will also be instantiated as objects on the heap, except for the value types?
Why isn't there a HairStyle object connected to the Guy object in this case?
Yes, you are rigth when say "property like methods", but this methods needs to work with some type, and it can be base type or object as well.
I think it's better that we pay attention to the difference between class and object first.
Many people get confused by the difference between a class and an object. The difference is simple and conceptual. A class is a template for objects. A class defines object properties, including a valid range of values and a default value. A class also describes object behavior. An object is a member or an "instance" of a class. An object has a state in which all of its properties have values that you either explicitly define or that are defined by default settings.
And now, let's check out the properties:
Properties are attributes or features that characterize classes. While classes are groups of objects, an instance is a specific object that actually belongs to a class.
I'm not exactly sure what you're asking but maybe this will help.
The properties you're looking at are like, you said, getters and setters of a certain type (string, int, Outfit etc).
The "Full" property below is what's going on under the hood (as far as I know)
public class Props
{
//Syntactic Sugar
public string? MyProperty { get; set; }
//What's actually happening
private string? myProperty_full;//This is the field that holds the value
public string? MyProperty_Full
{
get => myProperty_full;
//value is whatever the user sets MyProperty_Full to
set => myProperty_full = value;
}
}
In the case of Clothes property.
There is a private backing field of type Outfit with some getters and setters for manipulating it.

Entity Framework:Why the collection type of entity class need to be instanced in the default constructor?

I am using Visual Studio to build a code first model of NorthWind database automatically. I have some questions.
I found that if the entity class has a collection, then the is collection always instantiated in the default constructor. Why we need to do that?
The ICollection<T> is instantiated as a HashSet<T> in the default constructor. Why is HashSet<T> used? Can i use List<T> or something else?
Why is the navigation property at one side (one to many relation) is ICollection<T> and virtual?
To Implement the entity class in the way I mention above, I think there must be some benefits can be brought. Can you tell me why?
public partial class Orders
{
public Orders()
{
Order_Details = new HashSet<Order_Details>();
}
public virtual ICollection<Order_Details> Order_Details { get; set; }
}
I found that if the entity class has a collection, then the is collection always instantiated in the default constructor. Why we need to do that?
You don't. It just needs to be instantiated before you start adding stuff to it.
The ICollection is instantiated as a HashSet in the default constructor. Why is HashSet used? Can i use List or something else?
You can use anything that implements ICollection<T> as the concrete implementation.
Why is the navigation property at "one" side (one to many relation) is ICollection and virtual?
ICollection<T> is the interface that EF expects for navigation properties. It provides the minimal interface necessary to represent that type of relationship. It is virtual so that EF can insert a proxy at runtime to detect changes to the property. If you decide not to make it virtual, you will need to manually inform EF about changes to the property.
I found that if the entity class has a collection, then the is collection always instantiated in the default constructor. Why we need to do that?
For the same reason you instantiate any reference type field in your class. When you access it for the first time, it will be usable and not throw a NRE.
The ICollection is instantiated as a HashSet in the default constructor. Why is HashSet used? Can i use List or something else?
A HashSet<T> is used because it guarantees that two values which are equal to each other (which are equality checked by looking at their GetHashCode and Equals methods) only appear once in the collection.
And yes, you can change the concrete type to any type which implements ICollection<T>.
Why is the navigation property at "one" side (one to many relation) is ICollection and virtual?
Because if a certain object has a one-to-many relationship, it means that each instance (one) will have a collection of a different type (many). It is virtual to allow EF to inject proxies at runtime.

Using CollectionAssert

If I had a custom class that inherits from Collection called LookUpValueCollection that handle only types of the class LookUpValueCollection, to use the method CollectionAssert with Visual Studio test Do I need to implement the method IEqual to handle the comparison? Because I used and despite of two collection are similar still says that the objets inside are different.
Yes, the elements of the collection need to override Equals (and GetHashCode). Otherwise, the elements will be compared by reference, so they won't be considered equal if they're not the same instance.

What object types should I use for testing generic collections?

What object types are best for writing unit tests for generic collections? Obviously if I'm using them in a specific way in my application, it's best to test with those types. But if I'm not, and simply creating a utility library, which types should I use?
I'm trying to avoid any pitfalls with specific object types. For example, when testing a generic dictionary structure, I know that the GetHashCode and Equals methods are very important in ensuring a valid test. I'm worried that if I simply use dummy object instances (var a = new object();), that I run into problems with these methods not being robust enough.
I'm considering using GUID instances for all of my unit testing, because of their necessarily unique constraints. However, being structs, I cannot test for equivalent references should I need to.
Lastly, are there any other gotchas to watch out for when using a specific object implementation (like object or GUID) in place of generic types for unit test purposes?
If you want to be thorough, you should test with several types:
A value type, such as int
A reference type which uses referential equality
A reference type with overridden Equals+GetHashCode
Passing in an IEqualityComparer<T>
double or float for their strange NaN semantics.
Not every test needs to be done for all of them. But I'd add at least one test for each of them.
you could use an ArrayList. populate it with custom objects, one of them being an integer like a primary key, and the others being your data. It is not a generic collection but very handy to use.
class MyObject
{
public int myPrimaryKey {get; set;}
public object myData {get; set;}
{
Then all you have to do is add it to an ArrayList:
var a = new ArrayList();
a.add(new MyObject{myPrimaryKey = 1, object = 'some value'});
Hope this is what you were looking for.
If you mean that you want to test the generic collections from System.Collections namespace, then this is a wrong approach to testing.
Your test should cover your code only, but not other things which are not developed by you.

Returning an immutable collection when the items must be mutable initially

One example of the general case:
public class Validator
{
// ...
public ReadOnlyCollection<InvalidContainer> ContainersUnderMinimum
{
get { return _containersUnderMinimum.AsReadOnly(); }
}
}
public class InvalidContainer
{
// ...
public int LowestVolume { get; set; }
}
The Validator class above takes a collection of other items in its constructor, then adds invalid items to the internal List. Each container has many sub-containers (think a rack of test tubes), and the class wants to find the lowest volume. The constructor is adding to the list when an item (tube) is not found, and updating the existing list object when an item is found.
The problem is that the Validator wants to return a read-only collection of immutable objects, but the objects (InvalidContainers) must be mutable post-construction so that values can be (essentially) accumulated.
Refactoring to use an interface (IInvalidContainer) causes headaches, as generic collections cannot be cast to collections of a base type.
What are some good patterns or practices to solve this issue?
EDIT: To clarify, the intention is to have the property value (the collection) be immutable. I understand that ReadOnlyCollection only enforces immutability of the collection, not of the collection items. Normally I would make the items immutable, but I can't in this (and similar) cases. However, I only want the items mutated at the time the Validator class is being constructed. Preventing callers from doing unwise casting is not a design goal; the goal is to avoid tempting callers with a settable public property.
EDIT: Changed the title for clarity.
EDIT: Here's the refactored version (based on suggestions from LBushkin and recursive):
public IEnumerable<IInvalidContainer> ContainersUnderMinimum
{
get
{
return _containersUnderMinimum.Cast<IInvalidContainer>();
}
}
If I understand your problem correctly, you want to return a collection of immutable types, but internally retain a mutable collection. The typical way of doing so, is to create a base type (or interface) for your type that is immutable and return that.
You can either cast items to that type (a weak form of immutability control), or you can create wrapper objects and return those (a strong type of control). Wrapper objects can be more expensive to create - but they prevent external code from simply being able to perform a type-cast to get around immutability. This is, by the way, the mechanism that ReadOnlyCollection<T> uses to return immutable collections.
To overcome that fact that collection types have limited casting support, you can use LINQ to return a immutable copy of the immutable type:
_containersUnderMinimum.Cast<IInvalidContainer>().ToList().AsReadOnly()
This creates a copy of the collection - but it may be good enough - if you don't need to the collection to reflect changes at runtime.
Also, be aware that ReadOnlyCollection does not require (or enforce) immutability of the elements of the collection. Rather, it prevents the receiver from being able to add or remove elements - changing existing elements in the collection is still possible.
Actually, it is possible to cast generic collections:
ReadOnlyCollection<IInvalidContainer> result =
_containersUnderMinimum.Cast<IInvalidContainer>().ToList().AsReadOnly();
However, this does not stop the consumer from casting the elements back.
If your mutable objects can only be changed via methods, I would suggest that you include within your mutable type a reference which, if non-null, will identify an instance of an immutable type which encapsulates that same data. Your mutable type should include a method to create an immutable copy; that method should make and cache a new immutable object if it doesn't already hold a reference to one. Otherwise it should return the cached reference. Any mutating method should invalidate the immutable-object reference. Using that approach, one should be able to avoid having to make repeated copies of objects that are never mutated.
Maybe I'm misunderstanding, but a ReadOnlyCollection only implies that the collection is ReadOnly, not the objects themselves...

Categories