InvalidCastException when passing a mocked dependency into a function - vb.net

I am using Rhino Mocks along with nUnit to attempt to test my function IsApprovable() on an object. The function I am testing relies on another object "UserManager" that needs to be passed in. I am attempting to mock an instance of UserManager so I can specify the result of another function GetApproverDependantsList()
My issue is that when I mock the object and pass it into the function I am testing I get the following InvalidCastException:
Unable to cast object of type 'Castle.Proxies.IUserManagerProxye15b431a53ca4190b7ffbdf5e241e2bb' to type 'MyNamespace.Users.UserManager'.
I am new to this so I am not really sure if I am doing things correctly... Here is the sample mocking code I am using:
Dim helper As New BookingManagerHelper()
Dim booking As Booking = GetDummyBooking() 'method to get a booking in suitable state
Dim parameters As Collection(Of Parameter) = GetDummyParameters() 'factory method, as above
Dim mockedUserManager = MockRepository.GenerateMock(Of Users.IUserManager)()
'I have created a dummy function called GetUserCollectionWithDependant() to create the results I need the mocked function to return...
mockedUserManager.Stub(Function(x) x.GetApproverDependantsList(-1)).[Return](GetUserCollectionWithDependant(1))
'It's the line below where I find my exception...
Assert.AreEqual(True, helper.IsApprovable(booking, mockedUserManager, parameters))
The function I am attempting to test looks like the following:
Public Function IsApprovable(ByVal Booking As Booking , ByVal UserManager As Users.UserManager, Optional ByVal Parameters As Collection(Of Parameter) = Nothing) As Boolean
'various logic checks are performed on the objects passed in
End Function
Some things to note:
UserManager implements the interface IUserManager
UserManager contains additional properties and functions that are not defined by the interface
UserManager also inherits from a base class (do I need to override base properties?)
I can post more code if needed. Thanks in advance.

I am no expert in VB.NET but IsApprovable expects a UserManager instance. The mock is of type IUserManager. Maybe you want to adjust IsApprovable to use a IUserManager instance.

Related

From A Method With In The Class Return An Instance Of The Class As An Interface Type That The Class Implements

what I'm trying to archive with the code below is to have the GetInstance generic function take in an interface type that SystemVars implements (say IAuthentication) then create an instance of SystemVars and return it as interface type T.
The problem I an having is that no matter what casting method I try I can't find a way to return the new instance of SystemVars as T. The line in the GetInstance method Return <CastingFunction>(New SystemVars,T) always fails to compile with the error message saying Value of type SystemVars cannot be converted to 'T'.
How do I return the instance of the class as the interface type that was passed into T?
Imports System.Drawing
Public Class SystemVars
Implements IAuthentication,
IAuthorization,
IApplicationStarting
Private Sub New()
End Sub
Public Shared Function GetInstance(Of T)() As T
Return DirectCast(New SystemVars, T)
End Function
Public ReadOnly Property Username As String _
Implements IAuthentication.Username,
IAuthorization.Username
Get
Return _userName
End Get
End Property
Public ReadOnly Property Rolls As List(Of String) _
Implements IAuthorization.Rolls
Get
Return _rolls
End Get
End Property
Public ReadOnly Property InstallationId As Guid _
Implements IAuthentication.InstallationId,
IApplicationStarting.InstallationId
Get
Return _installationId
End Get
End Property
Public ReadOnly Property MainWindowStartUpPlacement As Rectangle _
Implements IApplicationStarting.MainWindowStartUpPlacement
Get
Return _mainWindowStartUpPlacement
End Get
End Property
'........
Private Shared _userName As String
Private Shared _rolls As List(Of String)
Private Shared _installationId As Guid
Private Shared _mainWindowStartUpPlacement As Rectangle
End Class
You can make an otherwise illegal cast work by passing through Object.
Public Shared Function GetInstance(Of T)() As T
Return DirectCast(CObj(New SystemVars), T)
End Function
You will get a runtime error if the cast isn't possible; as noted in the comments, this strategy is chucking type safety out the window and basically telling the compiler, "Don't bother me, I know what I'm doing." The runtime will throw an InvalidCastException on failure if you don't test and throw yourself. You can test using Type.IsAssignableFrom if you want to create a more developer-friendly error message; there isn't much context available in the debugger at the point of failure, though it may be pretty obvious if you look up the call stack.
For just three interfaces, it might be better to do three separate specific functions rather than a generic version, especially considering that the functions are necessarily Shared (and thus can't themselves be part of an interface).
You might also consider a design that includes a Dependency Injection container. In this kind of design, there would be a configuration step that would associate the interfaces with SystemVars as the implementation, then the client would ask the container for an instance of the interface and receive a SystemVars object.
The rough way that the three options (the third being to cast the SystemVars object to the requested interface) would look in code is:
'Casting a received object to a requested interface
Dim asInterface = DirectCast(SystemVars.GetInstance(), IAuthorization)
'Using a custom casting function on SystemVars
Dim asInterface = SystemVars.GetInstance(Of IAuthorization)
'Using a DI container
'Behavior if the interface isn't supported depends on the container
Dim asInterface = container.GetInstance(Of IAuthorization)
Note that TryCast could be used instead of DirectCast, in which case the result would be Nothing if the interface isn't supported.

CallByName with different arguments

The Function I want to get from CallByName is the following
public PredictionEngine<TSrc, TDst> CreatePredictionEngine<TSrc, TDst>(ITransformer transformer)
Normally I call this function as following:
predEng = CreatePrediction(NewData,NewDataPrediction)(model)
(NewData and NewDataPrediction are classes)
But now Im creating a class dynamically, so I would need to call that function with the new created class.
I have tried every combination but I just can't.
TryCast(CallByName(mlContext.Model, "CreatePredictionEngine", CallType.Method, model), obj.GetType,NewDataPrediction)
(obj is a type of the new class)

.Net Error LINQ - new classname with

Why would VS keep saying to add this?
Sub New()
' TODO: Complete member initialization
End Sub
Since you have a constructor that takes parameters, a default, parameterless constructor is not created for you automatically.
Your LINQ statement is not calling your parameterized constructor, it need a parameterless constructor.
Basically, when you code this:
Select New CommunityEvent With {.Day = sRecord(0), etc. }
What gets generated is this
Dim obj As New CommunityEvent() 'Uses parameterless constructor
obj.Day = sRecord(0)
'etc.
When you remove the CommunityEvent With part, then it doesn't use your class, it creates an anonymous type instead.

how can we call ninjects service locator in code?

first time on stackoverflow + ninject (IoC's)
I have a situation in which I have Business Objects Implemented in a way that they have Models in them... i.e.
Public Class Whatever
Implements IWhatEver
Public Property Id as Integer
Public Property Name as String
Public Function SetWhatEver() as Whatever
'Do Whatever Settings
End Function
End Class
I am using ninject for DI (Dependency Injection) however the issue was that I couldn't use an Interface as a model being passed in an action, therefore I am trying to make a custom modelbinder and want to use the bindingContext.ModelType to pass to ninject and ninject to resolve it for me and so I can do my binding with metadata
Public Overrides Function BindModel(controllerContext As ControllerContext, bindingContext As ModelBindingContext) As Object
Dim modelType = ninjectPleaseResolve(bindingContext.ModelType)
Dim metaData = ModelMetadataProviders.Current.GetMetadataForType(Nothing, modelType)
bindingContext.ModelMetadata = metadata
Return MyBase.BindModel(controllerContext, bindingContext)
End Function
I hope this makes sense... I have tried looking for answers BTW and nothing online is making sense to me, so please can you explain in simple terms..
EDIT
I am adding the controller code below to give you a better understanding of what I am trying to do.. I don't want to use the Whatever class instead I want to use the IWhatever in the controller for my processing... please see below an example...
Public Class MainController
Inherits System.Web.Mvc.Controller
Dim repository As IWhatever
Public Sub New(pWhatever As IWhatever)
repository = pWhatever
End Sub
Function Index(myValues As IWhatever) As ActionResult
'So I can process these values to my liking...
repository.SetWhatEver(myValues)
' and then perhaps other functions like...
repository.Save()
Return View()
End Function
I hope this makes a little sense now..
the issue was that I couldn't use an Interface as a model being passed
in an action
You shouldn't pass in services through the action method. You should pass services in through the constructor. This way your container can build up the controller and all related objects for you and this way you don't have to write a custom model binder.

Issue with passing parameters by reference into public shared methods

I have a List(Of AddlInfo) with AddlInfo being an object.
I'm trying to pass addlInfoList by reference into a function of another class:
Public Shared Sub SortAddlInfo(ByRef addlInfoList As List(Of AddlInfo))
addlInfoList.Sort(AddressOf Comparer)
End Sub
Private Function Comparer(ByVal x As AddlInfo, ByVal y As AddlInfo) As Integer
Dim result As Integer = x.AddlInfoType.CompareTo(y.AddlInfoType)
Return result
End Function
This works if I'm not passing the reference into another class, but when I try to do this, I get the following error:
Overload resolution failed because no accessible 'Sort' can be called with these arguments:
'Public Sub Sort(comparison As System.Comparison(Of AddlInfo))': Cannot refer to an instance member of a class from within a shared method or shared member initializer without an explicit instance of the class.
'Public Sub Sort(comparer As System.Collections.Generic.IComparer(Of AddlInfo))': 'AddressOf' expression cannot be converted to 'System.Collections.Generic.IComparer(Of MyProject.AddlInfo)' because 'System.Collections.Generic.IComparer(Of MyProject.AddlInfo)' is not a delegate type.
I could put the methods back into the calling class, but I'd like to be able to call these methods from different classes within my application.
I could also instantiate a fresh List in the methods, but why? Seems silly.
Any way around this? (Or do I need to explain more?)
Thanks in advance!
Try putting your compare function into a class that implements IComparer.