When using Moq with Verify, to assert that a certain method has been called with specified parameters, different kind of syntax is possible; one is the "It" syntax, like this
mock.Verify(c => c.SomeMethod(It.Is<string>(s => s == ExpectedString)));
What happens here is that the parameter that SomeMethod is called with, is checked for equality with ExpectedString. Another possible syntax is without "It":
mock.Verify(c => c.SomeMethod(ExpectedString));
which should give the same result. From what I have been able to find on different forums, the difference is that the latter is an identify check (reference equals) (except for value types).
However, my question is when the parameter is of a type Collection type. In .NET, Equals on Collection<T> is just inherited from object, so the following verify:
mock.Verify(c => c.SomeMethod(new Collection<string> { ExpectedString }));
should not be possible to pass, given that the collection is instantiated in the verify, and thus cannot possibly be the same instance that is instantiated in the production code. Nevertheless, it works, which indicates that Moq does a CollectionAssert or something like that, contrary to what information I could find.
Here is a code example that illustrates the behaviour, the test passes, but I think it should fail if Moq had used reference equals comparison.
[TestMethod]
public void Test()
{
var mock = new Mock<IPrint>();
const int ExpectedParam = 1;
var test = new TestPrinter { Printer = mock.Object, Expected = ExpectedParam };
test.Do();
mock.Verify(c => c.Print(new Collection<int> { ExpectedParam }));
}
public interface IPrint
{
void Print(Collection<int> numbers);
}
public class TestPrinter
{
public IPrint Printer { get; set; }
public int Expected { get; set; }
public void Do()
{
Printer.Print(new Collection<int> { Expected });
}
}
Does anyone know if this is expected behaviour of Moq (version 4.1)? Was the behaviour changed at some version level?
This is desired behaviourand was added to moq in January 2009 (version 3.0.203.1).
If moq finds an IEnumerable, it uses SequenceEqual to compare the actual argument and the argument used in the setup, otherwise it just uses Equals.
Here's the relevant bit of code:
internal class ConstantMatcher : IMatcher
{
...
public bool Matches(object value)
{
if (object.Equals(constantValue, value))
{
return true;
}
if (this.constantValue is IEnumerable && value is IEnumerable)
{
return this.MatchesEnumerable(value);
}
return false;
}
private bool MatchesEnumerable(object value)
{
var constValues = (IEnumerable)constantValue;
var values = (IEnumerable)value;
return constValues.Cast<object>().SequenceEqual(values.Cast<object>());
}
}
Related
One of the great advantages is supposed to be value based/structural equality, but how do I get that to work with collection properties?
Concrete simple example:
public record Something(string Id);
public record Sample(List<Something> something);
With the above records I would expect the following test to pass:
[Fact]
public void Test()
{
var x = new Sample(new List<Something>() {
new Something("x1")
});
var y = new Sample(new List<Something>() {
new Something("x1")
});
Assert.Equal(x, y);
}
I understand that it is because of List being a reference type, but does it exist a collection that implements value based comparison? Basically I would like to do a "deep" value based comparison.
Records don't do this automatically, but you can implement the Equals method yourself:
public record Sample(List<Something> something) : IEquatable<Sample>
{
public virtual bool Equals(Sample? other) =>
other != null &&
Enumerable.SequenceEqual(something, other.something);
}
But note that GetHashCode should be overridden to be consistent with Equals. See also implement GetHashCode() for objects that contain collections
I have found a very strange behavior in C# (.net core 3.1) for comparison of anonymous objects that I cannot explain.
As far as I understand calling Equals for anonymous objects uses structural equality comparison (check e.g. here). Example:
public static class Foo
{
public static object GetEmptyObject() => new { };
}
static async Task Main(string[] args)
{
var emptyObject = new { };
emptyObject.Equals(new { }); // True
emptyObject.Equals(Foo.GetEmptyObject()); // True
}
That looks correct. But the situation gets totally different if I move 'Foo' to another assembly!
emptyObject.Equals(Foo.GetEmptyObject()); // False
Exactly same code returns a different result if the anonymous object is from another assembly.
Is this a bug in C#, implementation detail or something that I do not understand alltogether?
P.S. Same thing happens if I evaluate the expression in quick watch (true in runtime, false in quick watch):
It's an implementation detail that you don't understand.
If you use an anonymous type, the compiler has to generate a new type (with an unspeakable name, such as <>f__AnonymousType0<<A>j__TPar>), and it generates this type in the assembly which uses it.
It will use that same generated type for all usages of anonymous types with the same structure within that assembly. However, each assembly will have its own anonymous type definitions: there's no way to share them across assemblies. Of course the way around this, as you discovered, is to pass them around as object.
This restriction is one of the main reasons why there's no way of exposing anonymous types: you can't return them from methods, have them as fields etc. It would cause all sorts of issues if you could pass them around between assemblies.
You can see that at work in SharpLab, where:
var x = new { A = 1 };
causes this type to be generated in the same assembly:
internal sealed class <>f__AnonymousType0<<A>j__TPar>
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly <A>j__TPar <A>i__Field;
public <A>j__TPar A
{
get
{
return <A>i__Field;
}
}
[DebuggerHidden]
public <>f__AnonymousType0(<A>j__TPar A)
{
<A>i__Field = A;
}
[DebuggerHidden]
public override bool Equals(object value)
{
global::<>f__AnonymousType0<<A>j__TPar> anon = value as global::<>f__AnonymousType0<<A>j__TPar>;
if (anon != null)
{
return EqualityComparer<<A>j__TPar>.Default.Equals(<A>i__Field, anon.<A>i__Field);
}
return false;
}
[DebuggerHidden]
public override int GetHashCode()
{
return -1711670909 * -1521134295 + EqualityComparer<<A>j__TPar>.Default.GetHashCode(<A>i__Field);
}
[DebuggerHidden]
public override string ToString()
{
object[] obj = new object[1];
<A>j__TPar val = <A>i__Field;
obj[0] = ((val != null) ? val.ToString() : null);
return string.Format(null, "{{ A = {0} }}", obj);
}
}
ValueTuple had the same challenges around wanting to define types anonymously but still pass them between assemblies, and solved it a different way: by defining ValueTuple<..> in the BCL, and using compiler magic to pretend that their properties have names other than Item1, Item2, etc.
I am building a simple Guard API to protect against illegal parameters being passed to functions and so on.
I have the following code:
public static class Guard
{
public static GuardArgument<T> Ensure<T>(T value, string argumentName)
{
return new GuardArgument<T>(value, argumentName);
}
}
public class GuardArgument<T>
{
public GuardArgument(T value, string argumentName)
{
Value = value;
Name = Name;
}
public T Value { get; private set; }
public string Name { get; private set; }
}
// Example extension for validity checks
public static GuardArgument<T> IsNotNull<T>(this GuardArgument<T> guardArgument, string errorMessage)
{
if (guardArgument.Value == null)
{
throw new ArgumentNullException(guardArgument.Name, errorMessage);
}
return guardArgument;
}
At the moment the code can be used in a similar way to (note this is just a dumb example):
void DummyMethod(int? someObject) {
Guard.Ensure(someObject, "someObject")
.IsNotNull()
.IsGreaterThan(0)
.IsLessThan(10);
}
This all works fine. What I want to be able to do now is extend the API to include child properties in the checks in the following way:
Guard.Ensure(someObject, "someObject")
.IsNotNull()
.Property(
(x => x.ChildProp1, "childProp1")
.IsNotNull()
.IsGreaterThan(10)
)
.Property(
(x => x.ChildProp2, "childProp2")
.IsNotNull()
.IsLessThan(10)
);
Obviously the new .Property method needs to return the parent GuardArgument in order to chain. Furthermore the child property needs to be able to use the existing check methods (IsNotNull() etc) to avoid code duplication.
I cannot work out how to construct the lambda/Property function parameters or where the .Property method should be located - i.e. should it be a property on the GuardArgument or somewhere else, or even if there is a better structure to the API.
The following function allows for a similar syntax to what you want.
public static GuardArgument<T> Property<T, TProp>(this GuardArgument<T> guardArgument, Func<T, TProp> getProperty, string propertyName, Action<GuardArgument<TProp>> validate)
{
GuardArgument<TProp> propertyGuardArgument = new GuardArgument<TProp>(getProperty(guardArgument.Value), propertyName);
validate(propertyGuardArgument);
return guardArgument;
}
The function creates a new GuardArgument for the selected property and then passes this into the Action parameter to allow you to validate as you wish.
This also allows infinite chaining of properties, although I'm not sure that would be particularly readable.
Usage:
Guard.Ensure(someObject, "someObject")
.IsNotNull()
.Property(x => x.ChildProp1, "childProp1", childProp1 =>
childProp1.IsNotNull()
.IsLessThan(10)
.Property(y => y.InnerChildProperty, "innerChildProperty", innerChildProperty =>
innerChildProperty.IsNotNull()
)
)
.Property(x => x.ChildProp2, "childProp2", childProp2 =>
childProp2.IsNotNull()
.IsGreaterThan(10)
);
I think you have no benefit from putting the property checks in the chain of the parent object checks. So I would recommend to make one chain for the parent object and for each property another chain. This is much more readable:
Guard.Ensure(a, "a")
.IsNotNull("a is null");
Guard.Ensure(a.p0, "a.p0")
.IsGreaterThan(10);
Guard.Ensure(a.p1, "a.p1")
.IsGreaterThan(5);
I think you are reinventing a wheel here. Install this extension - Code Contracts and here is docs how to use it.
In addition to code based asserts similar to yours, i.e. :
public int[] Bar(){
Contract.Ensures( Contract.ForAll(0, Contract.Result<int[]>().Length, index => Contract.Result<int[]>()[index] > 0));
....
}
or
Contract.Requires<ArgumentNullException>( x.Value.NestedObject != null, ”x.Value.NestedObject” );
But also has attributes and extensive set of functions for checking interfaces, nice pre- and post- conditions etc. check it out!
I have a class like this :
public class Test
{
public string STR1{ get; set; }
public INT INT1{ get; set; }
public DOUBLE DBL1{ get; set; }
public DATETIME DT1{ get; set; }
}
Normally, before saving the object, i will have to check all the properties inside this Class, and return a warning message if there is any empty/null property. There is easy way to do this by simply check each property like this :
if (string.IsNullOrEmpty(t.STR1))
return "STR1 is empty"
if (t.INT1 == 0)
return "INT1 = 0";
if (t.DBL1 == 0)
return "DBL1 = 0";
if (t.DT1 == DateTime.MinValue)
return "DT1 is empty"
But what if my class has more properties, actually it contains about 42 properties now, and still growing up. So i was thinking for a "cleaner" way to perform this check, and i found this topic which is quiet similar to my issue : Reflection (?) - Check for null or empty for each property/field in a class?
But this solution does not meet my need as i have to list the values that = null/empty string/0/DateTime.MinValue
Believe me, i wanted to post my "tried code" but i can't figure out a sensible LINQ query for this task (i'm a novice in C#)
Any help is greatly appreciated !
Since you need to test objects of different types, you can combine the solution from the linked question with use of dynamic to dispatch to the proper method.
First, define an overloaded method for each type.
private static IsEmpty(string s) { return string.IsNullOrEmpty(s); }
private static IsEmpty(double f) { return f == 0.0; }
private static IsEmpty(int i) { return i == 0; }
private static IsEmpty(DateTime d) { return d == DateTime.MinValue; }
Now you can use these methods in your check:
List<string> emptyProperties = typeof(MyType).GetProperties()
.Select(prop => new { Prop = prop, Val = prop.GetValue(obj, null) } )
.Where(val => IsEmpty((dynamic)val.Val) // <<== The "magic" is here
.Select(val => val.Prop.Name)
.ToList();
The tricky part of the code casts the value to dynamic, and then tells the runtime to find the most appropriate IsEmpty method for it. The downside to this approach is that the compiler has no way of telling whether the method is going to be found or not, so you may get exceptions at runtime for properties of unexpected type.
You can prevent these failures by adding a catch-all method taking object, like this:
private static IsEmpty(object o) { return o == null; }
Consider the following (heavily simplified) code:
public T Function<T>() {
if (typeof(T) == typeof(string)) {
return (T) (object) "hello";
}
...
}
It's kind of absurd to first cast to object, then to T. But the compiler has no way of knowing that the previous test assured T is of type string.
What is the most elegant, idiomatic way of achieving this behavior in C# (which includes getting rid of the stupid typeof(T) == typeof(string), since T is string can't be used)?
Addendum: There is no return type variance in .net, so you can't make a function overload to type string (which, by the way, is just an example, but one reason why association end redefinition in polymorphism, e.g. UML, can't be done in c#). Obviously, the following would be great, but it doesn't work:
public T Function<T>() {
...
}
public string Function<string>() {
return "hello";
}
Concrete Example 1: Because there's been several attacks to the fact that a generic function that tests for specific types isn't generic, I'll try to provide a more complete example. Consider the Type-Square design pattern. Here follows a snippet:
public class Entity {
Dictionary<PropertyType, object> properties;
public T GetTypedProperty<T>(PropertyType p) {
var val = properties[p];
if (typeof(T) == typeof(string) {
(T) (object) p.ToString(this); // magic going here
}
return (T) TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(val);
}
}
Concrete Example 2: Consider the Interpreter design pattern:
public class Expression {
public virtual object Execute() { }
}
public class StringExpression: Expression {
public override string Execute() { } // Error! Type variance not allowed...
}
Now let's use generics in Execute to allow the caller to force a return type:
public class Expression {
public virtual T Execute<T>() {
if(typeof(T) == typeof(string)) { // what happens when I want a string result from a non-string expression?
return (T) (object) do_some_magic_and_return_a_string();
} else if(typeof(T) == typeof(bool)) { // what about bools? any number != 0 should be True. Non-empty lists should be True. Not null should be True
return (T) (object) do_some_magic_and_return_a_bool();
}
}
}
public class StringExpression: Expressiong {
public override T Execute<T>() where T: string {
return (T) string_result;
}
}
If you're making these types of checks in a generic method, I'd rethink your design. The method is obviously not truly generic - if it were, you wouldn't need specific type checking...
Situations like this typically can be handled more cleanly by a redesign. One alternative is often to provide an overload of the appropriate type. Other design alternatives which avoid the type-specific behavior exist, as well, such as Richard Berg's suggestion of passing in a delegate.
using System;
using System.Collections.Generic;
using System.Linq;
namespace SimpleExamples
{
/// <summary>
/// Compiled but not run. Copypasta at your own risk!
/// </summary>
public class Tester
{
public static void Main(string[] args)
{
// Contrived example #1: pushing type-specific functionality up the call stack
var strResult = Example1.Calculate<string>("hello", s => "Could not calculate " + s);
var intResult = Example1.Calculate<int>(1234, i => -1);
// Contrived example #2: overriding default behavior with an alternative that's optimized for a certain type
var list1 = new List<int> { 1, 2, 3 };
var list2 = new int[] { 4, 5, 6 };
Example2<int>.DoSomething(list1, list2);
var list1H = new HashSet<int> { 1, 2, 3 };
Example2<int>.DoSomething<HashSet<int>>(list1H, list2, (l1, l2) => l1.UnionWith(l2));
}
}
public static class Example1
{
public static TParam Calculate<TParam>(TParam param, Func<TParam, TParam> errorMessage)
{
bool success;
var result = CalculateInternal<TParam>(param, out success);
if (success)
return result;
else
return errorMessage(param);
}
private static TParam CalculateInternal<TParam>(TParam param, out bool success)
{
throw new NotImplementedException();
}
}
public static class Example2<T>
{
public static void DoSomething(ICollection<T> list1, IEnumerable<T> list2)
{
Action<ICollection<T>, IEnumerable<T>> genericUnion = (l1, l2) =>
{
foreach (var item in l2)
{
l1.Add(item);
}
l1 = l1.Distinct().ToList();
};
DoSomething<ICollection<T>>(list1, list2, genericUnion);
}
public static void DoSomething<TList>(TList list1, IEnumerable<T> list2, Action<TList, IEnumerable<T>> specializedUnion)
where TList : ICollection<T>
{
/* stuff happens */
specializedUnion(list1, list2);
/* other stuff happens */
}
}
}
/// I confess I don't completely understand what your code was trying to do, here's my best shot
namespace TypeSquarePattern
{
public enum Property
{
A,
B,
C,
}
public class Entity
{
Dictionary<Property, object> properties;
Dictionary<Property, Type> propertyTypes;
public T GetTypedProperty<T>(Property p)
{
var val = properties[p];
var type = propertyTypes[p];
// invoke the cast operator [including user defined casts] between whatever val was stored as, and the appropriate type as
// determined by the domain model [represented here as a simple Dictionary; actual implementation is probably more complex]
val = Convert.ChangeType(val, type);
// now create a strongly-typed object that matches what the caller wanted
return (T)val;
}
}
}
/// Solving this one is a straightforward application of the deferred-execution patterns I demonstrated earlier
namespace InterpreterPattern
{
public class Expression<TResult>
{
protected TResult _value;
private Func<TResult, bool> _tester;
private TResult _fallback;
protected Expression(Func<TResult, bool> tester, TResult fallback)
{
_tester = tester;
_fallback = fallback;
}
public TResult Execute()
{
if (_tester(_value))
return _value;
else
return _fallback;
}
}
public class StringExpression : Expression<string>
{
public StringExpression()
: base(s => string.IsNullOrEmpty(s), "something else")
{ }
}
public class Tuple3Expression<T> : Expression<IList<T>>
{
public Tuple3Expression()
: base(t => t != null && t.Count == 3, new List<T> { default(T), default(T), default(T) })
{ }
}
}
Can you use as here?
T s = "hello" as T;
if(s != null)
return s;
I can't think of an "elegant" way to do this. As you say, the compiler can't know that the conditional has ensured that the type of T is string. As a result, it has to assume that, since there's no generalized way to convert from string to T, it's an error. object to T might succeed, so the compiler allows it.
I'm not sure I'd want an elegant way to express this. Although I can see where it'd be necessary to do explicit type checks like this in some situations, I think I'd want it to be cumbersome because it really is a bit of a hack. And I'd want it to stick out: "Hey! I'm doing something weird here!"
Ok, I took a run at it from several different angles and came up short. I would have to conclude that if your current implementation gets the job done you should take the win and move on. Short of some arcane emissions what you got is what you get.
But the compiler has no way of knowing
that the previous test assured T is of
type string.
Umm.... If I am not mistaken, generics is just code gen. The compiler generates a matching method for each distinct type found in the calling methods. So the compiler does know the type argument for the overload being called. Again; If I am not mistaken.
But overall, i think you are misusing the generic in this case, from what I can see, and as others have stated, there are more appropriate solutions..... which are unnamable unless you post code that completely specifies your requirements.
just my 2 pesos...