Moq - Object type casting and comparison - c#

I'm trying to use an IHTMLSelectElement with Moq. My code is something like:
// create a select element
var selectElem = new Mock<IHTMLSelectElement>(MockBehavior.Strict);
// set the select element
selectElem.Setup(f => f.length).Returns(20);
selectElem.Setup(f => f.name).Returns("selectElem");
// get the object
IHTMLSelectElement ihse = selectElem.Object;
Then in my production code method, I do:
var selectEle = (element as mshtml.IHTMLSelectElement);
if (selectEle != null)
{
My problem is that the type cast doesn't work because when using Moq the type is actually:
Castle.Proxies.IHTMLSelectElementProxy_1
Casting this to IHTMLSelectElement returns a null object.
Any idea on how I can make this work?

You'll need to make it injectable, either a property or a input parameter to a method, depending on the code. And then you can inject the with the MOQ object. The two lines of your code should not be doing the "as", it should be dealing with the correct type of element directly.

Related

How to cast an object to a generic type

I have a Mock list like this.
var MockList = new List<Mock>() {
new Mock<IBikeRepository>(MockBehavior.Strict),
new Mock<IGreeterService>(MockBehavior.Strict)
};
Now I get back one object like this.
var greeterServiceMock = this.MockList
.FirstOrDefault(mock => typeof(Mock<IGreeterService>) == mock.GetType());
Since MockList is of the type List<Mock>, the object that I pulled out from the list this.MockList is of the type Mock. But I can see the runtime type is Mock<IGreeterService>
Now I have to cast it to Mock<IGreeterService>
Is there a way here?
Edit
I think I got it.
var t = (Mock<IGreeterService>)greeterServiceMock!;
The ! at the end was the key. It was giving error without it and so I had to put the question here.
The reason you still need to cast is that FirstOrDefault will return a reference of the type of the list. You can filter ans cast at the same time by using OfType:
this.MockList.OfType<Mock<IGreeterService>>().FirstOrDefault();

An expression tree may not contain a call or invocation that uses optional arguments when mocking a function to return an object

Trying to set up a function to moq a call to a db to return an object
The function I am trying to mock is
res = ReservationMongo.GetById<res.Reservation>(request.ReferenceNumber);
Which is defined as
T GetById<T>(object id, bool fixId = false);
However in my set up I am encountering this error:
an expression tree may not contain a call or invocation that uses optional arguments
My setup:
Mock <IMongoDBService> resMock = new Mock<IMongoDBService>();
resMock.Setup(x => x.GetById<Reservation>(request.ReferenceNumber)).Returns(res1);
Optional parameters will also need to be included in the setup of the function to mock, even if they are not being explicitly used in the invocation of the member.
//...
Reservation res1 = new Reservation {
name = "bob",
age = "29",
occupant.name = "bob G",
occupant.name = string.empty
};
Mock<IMongoDBService> resMock = new Mock<IMongoDBService>();
resMock
.Setup(x => x.GetById<Reservation>(It.IsAny<int>(), It.IsAny<bool>())
.Returns(res1);
//...
Note the use of It.* argument matcher to allow for any argument values to be entered and still get the desired behavior
Reference Moq Quickstart
This is not explicitly a Moq issue, this is a expression tree issue. Expression trees do not allow optional arguments because that is something that is resolved at compile time as in CLR does not support the concept of optional arguments. So to fix your problem you will need to be explicit and put the value in, which if you are were counting on the default argument you are in luck just use that.

How to cast a type when referencing the assembly

Given
An extension method to convert a type via casting.
public static dynamic SwitchType(this dynamic ppo,
string classname, Action<dynamic> callback)
{
Type obj= Assembly.GetExecutingAssembly()
.GetTypes()
.Where(p => p.Name == classname)
.First();
var converted =(obj)ppo; <-- Error Here
callback(converted);
}
Problem
Compiler tells me it cannot find obj, so cast won't work.
Maybe I'm making this too complicated, but the ppo being passed in is a runtime object that I want to convert to a specific type of that same runtime object that was created earlier and contains specific static field text I need.
I've already validated the return of obj in other code so that part is working.
Further Information
We are parsing approximately 11 different tables in a web page all using the same class name. I want to write all the assertions in one place one time for all 11 rows. Each row has different content in it thus I have to have the instance of the saved class from when we created it, but all I have at runtime is the class name. Each time we call TestEditorFields we have a different page object with the same structure just different property values.
private void TestEditorFields(dynamic ppo)
{
Assert.IsTrue(ppo.ActualHeaderText == ppo.ExpectedHeaderText, "UTSC1160-The actual header text was not as expected");
Assert.IsTrue(ppo.ActualInputText == ppo.ExpectedInputText, "UTSC1170-The actual inputs text was not as expected");
Assert.IsTrue(ppo.ActualLabelText == ppo.ExpectedLabelText, "UTSC1180-The actual labels text was not as expected");
Assert.IsTrue(ppo.ActualRowHTML == ppo.ExpectedRowHTML, "UTSC1190-The HTML of the content rows was not as expected");
Assert.IsTrue(ppo.ActualSelectedText == ppo.ExpectedSelectedText, "UTSC1200-The Selected Options are not as expected");
Assert.IsTrue(ppo.ActualWarningText == ppo.ExpectedWarningText, "UTSC1210-The actual warning text is not as expected");
}
It seems like one of most powerful features of .NET is missed in a lot of questions: expression trees.
With expression trees you can generate an expression which can get compiled into a delegate to perform the desired conversion (bye bye reflection).
For example:
var paramExpr = Expression.Parameter(typeof(object));
var convertExpr = Expression.Convert(paramExpr, obj);
var lambdaExpr = Expression.Lambda(convertExpr, paramExpr);
var compiledExprDelegate = lambdaExpr.Compile();
Now you can call the delegate using Delegate.DynamicInvoke:
object conversionResult = compiledExprDelegate.DynamicInvoke(ppo);
Since you're working with DLR using dynamic, the above code should work in your scenario...
You can't cast an object instance to a Type that you don't know at compile time.
You need A base class or interface that the target type implement.
Or find a specific method by reflection on this object.
MethodInfo methodInfo = type.GetMethod(methodName);
methodInfo.Invoke(methodInfo, parametersArray);

Convert Array to Type Array

I'm creating a generic object from DB data:
object[] data = new object[dataReader.FieldCount];
dataReader.GetValues(data);
T t = (T)Activator.CreateInstance(typeof(T), data);
But, types with no constructor error on the third line. I want to add an if:
if (typeof(T).GetConstructor(data.TypesOf()) != null)
data.TypesOf() is actually an array - Type[] - that contains all types of the objects in data.
What is the equivalent to data.TypesOf() that really works?
Or do I need to iterate data and build it myself?
I'm assuming your object[] is containing values that are, for example, an int, a string and a float, and you are trying to resolve a constructor of the form public T(int,string,float). To get the types, you could use:
var types = Array.ConvertAll(data, x => x.GetType());
But that won't actually help you much here, since that is pretty-much what Activator.CreateInstance(typeof(T), data) has already tried to do - so if Activator failed, I don't see that it is obvious that you're going to do any better - unless the key difference is that the constructor is non-public and you are going to supply some BindingFlags.
Personally, though, I would suggest that it is easier to bind by name than by position; there are tools like dapper that will do all of that for you, allowing you to use simply:
var data = conn.Query<SomeType>(sql, args).ToList();
for example:
int userId = 12345;
var users = conn.Query<User>("select * from Users where Id = #userId",
new {userId}).SingleOrDefault();
As far as I understood you are trying to get types of elememnts of an object array. So you can do something like:
var ctorArgsTypes = data.Select(d => d.GetType()).ToArray()
var ctor = typeof(T).GetConstructor(ctorArgsType);
// check if appropriate ctor exists
if (ctor == null)
throw something
T t = (T)Activator.CreateInstance(typeof(T), data);
When you look at the Activator.CreateInstance(Type, Object[]) method, for the Object[] paramter :
An array of arguments that match in number, order, and type the
parameters of the constructor to invoke. If args is an empty array or
null, the constructor that takes no parameters (the default
constructor) is invoked.
So maybe in your case, your data object is not typed for each value (if getting from a DB or a file). You need to find a way to "type" your objects in your data array.
Just use Type.GetTypeArray(object[]).
https://msdn.microsoft.com/en-us/library/system.type.gettypearray(v=vs.110).aspx

how to populate ObjectResult from List<>

In order to test a method that uses a stored procedure, a fake method has been created. This method is to return a list of ints.
Something like this ...
public virtual ObjectResult<Nullable<int>> available_IDs( ... )
{
List<int?> fakeAvailableIDList = new List<int?>();
fakeAvailableIDList.Add(1);
fakeAvailableIDList.Add(2);
fakeAvailableIDList.Add(3);
ObjectResult<Nullable<int>> result = fakeAvailableIDList.All(m => m > 0);
return result;
}
which fails with
Cannot implicitly convert type 'bool' to 'System.Data.Objects.ObjectResult<int?>'
tried (amoungst other things)
ObjectResult<Nullable<int>> result = fakeAvailableIDList.All(m => m > 0);
which gives
Cannot implicitly convert type 'System.Collections.Generic.List<int?>' to 'System.Data.Objects.ObjectResult<int?>'
how can I get a List<> into ObjectResult ?
The line
fakeAvailableIDList.All(m => m > 0);
returns a boolean because .All returns True or False depending on whether or not all elements in the collection meet the specified condition.
So, a variable of type ObjectResult can't be set to a variable of type Bool.
The ObjectResult and ObjectResult<T> types have hidden constructors, which means you can't create instances at will. Also, the ObjectResult<T> type is sealed, which means it can't be extended. So, you might be out of luck if you're looking for an easy way to create an ObjectResult from an Enumerable.
The easiest thing to do, I think, would be to change the type used by the method you're trying to test. So, if that method has the signature:
void Foo(ObjectResult<int?> result);
Change it to:
void Foo(IEnumerable<int?> result);
That will allow you to create a fake collection with which the method can be tested, and you'll still be able to pass the method an ObjectContext<int?> type because ObjectContext<int?> extends IEnumerable<int?>.
I realize this has already been answered, but a solution I have come up with is to mock the specific Linq extension off of ObjectResult<T>.
For example:
Mock.Get(PortalEntitiesMock).Setup(m => m.ExecuteSqlQuery(It.Is<String>(x => x.ToUpper().StartsWith("SELECT"))).FirstOrDefault()).Returns<string>(p=>p).Verifiable();
So, you can mock individual items on a ObjectResult<T> object if not the actual ObjectResult<T>.

Categories

Resources