HowTo: Raise a event where event handler has a ref bool parameter - rhino-mocks

using RhinoMocks I would like to raise a event, where the event handler signature looks like:
MyEventHandler(int a value, ref bool handled) {..}
If I use:
myMock.Raise(x => x.MyEventHandler += null, aValue, handled);
I get the following Error message:
System.InvalidOperationException: Parameter #2 is System.Boolean but should be System.Boolean&
I tried it with:
myMock.Raise(x => x.MyEventHandler += null, aValue, ref Arg<bool>.Ref(Is.Anything(), handled).Dummy);
but that doesn't even compile...
What Is the right way to raise this event?

Take a look on following example
[Test]
public void RaiseEvent()
{
var mock = MockRepository.GenerateMock<IEventsRaiser>();
mock.GetEventRaiser(x => x.MyEvent += null).Raise(1, Arg<bool>.Ref(new Anything(), true).Dummy);
}
public delegate void MyEventHandler(int a, ref bool handled);
public interface IEventsRaiser
{
event MyEventHandler MyEvent;
}

Related

Invalid ModelState error message for Nullable types

I validate the input using ModelState.IsValid:
[HttpGet]
[Route("subjects")]
[ValidateAttribute]
public IHttpActionResult GetSubjects(bool? isActive = null)
{
//get subjects
}
If I pass in the uri ~/subjects/?isActive=abcdef, I get the error message:
The value 'abcdef' is not valid for Nullable`1.
If the input parameter is not nullable
public IHttpActionResult GetSubjects(bool isActive){
//get subjects
}
I get the error message:
The value 'abcdef' is not valid for Boolean.
I want to override the message if nullable type so I can maintain the message ("The value 'abcdef' is not valid for Boolean."). How can I do this since in the ModelState error I don't get the data type. I am implementing the validation as a custom ActionFilterAttribute (ValidationAttribute).
You can change callback that formats type conversion error messages. For example, let's define it right into Global.asax.cs:
public class WebApiApplication : HttpApplication
{
protected void Application_Start()
{
ModelBinderConfig.TypeConversionErrorMessageProvider = this.NullableAwareTypeConversionErrorMessageProvider;
// rest of your initialization code
}
private string NullableAwareTypeConversionErrorMessageProvider(HttpActionContext actionContext, ModelMetadata modelMetadata, object incomingValue)
{
var target = modelMetadata.PropertyName;
if (target == null)
{
var type = Nullable.GetUnderlyingType(modelMetadata.ModelType) ?? modelMetadata.ModelType;
target = type.Name;
}
return string.Format("The value '{0}' is not valid for {1}", incomingValue, target);
}
}
For not nullable types Nullable.GetUnderlyingType will return null, in this case we will use original type.
Unfortunately you cannot access default string resources and if you need to localize error message you must do it on your own.
Another way is to implement your own IModelBinder, but this is not a good idea for your particular problem.
Lorond's answer highlights how flexible asp.net web api is in terms of letting a programmer customize many parts of the API. When I looked at this question, my thought process was to handle it in an action filter rather than overriding something in the configuration.
public class ValidateTypeAttribute : ActionFilterAttribute
{
public ValidateTypeAttribute() { }
public override void OnActionExecuting(HttpActionContext actionContext)
{
string somebool = actionContext.Request.GetQueryNameValuePairs().Where(x => x.Key.ToString() == "somebool").Select(x => x.Value).FirstOrDefault();
bool outBool;
//do something if somebool is empty string
if (!bool.TryParse(somebool, out outBool))
{
HttpResponseMessage response = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest);
response.ReasonPhrase = "The value " + somebool + " is not valid for Boolean.";
actionContext.Response = response;
}
else
{
base.OnActionExecuting(actionContext);
}
}
Then decorate the action method in the controller with the action filter attribute

Using a Prism PubSub style event in C++/CLI

I'm trying to create an event aggregator in C++/CLI, I know that the valid syntax in C# would be as follows:
//C# code
public partial class Foo : UserControl, IView, IDisposable
{
private IEventAggregator _aggregator;
public Foo(IEventAggregator aggregator)
{
InitializeComponent();
this._aggregator = aggregator;
if (this._aggregator == null)
throw new Exception("null pointer");
_subToken =_aggregator.GetEvent<fooEvent>().Subscribe(Handler, ThreadOption.UIThread, false);
}
private SubscriptionToken _subToken = null;
private void Handler(fooEventPayload args)
{
//this gets run on the event
}
}
However directly converting this to C++/CLI gives the error "a pointer-to-member is not valid for a managed class" on the indicated line. Is there a workaround? I think it has something to do with how C# generates "Action".
//C++/CLI code
ref class Foo
{
public:
Foo(IEventAggregator^ aggregator)
{
void InitializeComponent();
this->_aggregator = aggregator;
if (this->_aggregator == nullptr)
throw gcnew Exception("null pointer");
//error in the following line on Hander, a pointer-to-member is not valid for a managed class
_subToken = _aggregator->GetEvent<fooEvent^>()->Subscribe(Handler, ThreadOption::UIThread, false);
private:
IEventAggregator ^ _aggregator;
SubscriptionToken ^ _addActorPipelineToken = nullptr;
void Handler(fooEventPayload^ args)
{
//this gets run on the event
}
}
You need to explicitly instantiate the delegate object, rather than allowing C# to do this for you.
_subToken = _aggregator->GetEvent<fooEvent^>()->Subscribe(
gcnew Action<fooEventPayload^>(this, &Foo::Handler), ThreadOption::UIThread, false);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Explicitly instantiate the delegate.
// ^^^^ Object to call the delegate on.
// ^^^^^^^^^^^^^ C++-style reference to the method.

How to access property of anonymous type?

Considering this IronPython script
def SensorEvent(d):
print d
print d.Message
... how do I access properties of d?
First line of the SensorEvent method successfully prints
{ Message = blah blubb }
however second line throws an exception:
'<>f_anonymousType[str]' object has no attribute 'Message'
Explanation
d is an instance of an anonymous type provided by an invoke from a C# method. I'm invoking it like this:
public static async void ExecutePyFunc(string name, dynamic data)
{
try
{
var f = strategyScope.GetVariable<Action<object>>(name);
if (f != null)
{
await Task.Run(() => f((object)data));
}
}
catch (Exception x)
{
StaticLog("[Callback Exception] Fehler beim Ausführen einer Python Funktion: {0}", x.Message);
}
}
d is a dictionary. Access it like so:
d['Message']
My solution using DynamicObject: I've introduced a class that converts an anonymous type into a known type by copying its properties via reflection (I don't need anything but the properties but it could probably be enhanced for use with fields, methods, functions as well).
Here's what I've come up with:
public class IronPythonKnownType : DynamicObject
{
public IronPythonKnownType(dynamic obj)
{
var properties = obj.GetType().GetProperties();
foreach (PropertyInfo prop in properties)
{
var val = prop.GetValue(obj);
this.Set(prop.Name, val);
}
}
private Dictionary<string, object> _dict = new Dictionary<string, object>();
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (_dict.ContainsKey(binder.Name))
{
result = _dict[binder.Name];
return true;
}
return base.TryGetMember(binder, out result);
}
private void Set(string name, object value)
{
_dict[name] = value;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
_dict[binder.Name] = value;
return true;
}
}
which effectively converts the anonymous object into something IronPython can handle.
Now I can do that:
def Blubb(a):
print a.Message
without getting the mentioned exception.

Weird error using C++/CLI - Cannot convert from parameter type to same parameter type

I've got the following code:
vlib_stage_decoding_config_t Decoder::CfgTransform(const DecodingConfig config)
{
vlib_stage_decoding_config_t cfg;
return cfg;
}
void Decoder::OpenDecode(const DecodingConfig config)
{
vlib_stage_decoding_config_t int_cfg = CfgTransform(config);
vlib_stage_decoding_open(&int_cfg);
}
Header file:
public ref struct DecodingConfig
{
};
I get the following error:
Error 1 error C2664: 'Video::Decoding::Decoder::CfgTransform' : cannot convert parameter 1 from 'const Video::Decoding::DecodingConfig' to 'const Video::Decoding::DecodingConfig' decoder.cpp
This is pretty nonsensical to me. Any ideas?
Try this:
vlib_stage_decoding_config_t Decoder::CfgTransform(DecodingConfig^ config)
{
vlib_stage_decoding_config_t cfg;
return cfg;
}
void Decoder::OpenDecode(DecodingConfig^ config)
{
vlib_stage_decoding_config_t int_cfg = CfgTransform(config);
vlib_stage_decoding_open(&int_cfg);
}
const is meaningless for managed types.
Despite your use of struct, DecodingConfig is a reference type, not a value type, so it cannot be passed without a tracking handle or a tracking reference. If you want DecodingConfig to be a value type, use value struct instead of ref struct and get rid of the ^s in your function arguments.

Rhino moq Property.value constraint

My following straight forward test doesn't pass (Though I feel it should). Either I am missing something or is not clear of Property.value constraint. please help me in understanding concept of property.value constraint.
public interface ISomeInterface
{
void SomeMethod(string x, string y);
}
public class SomeClassTest
{
[Test]
public void SomeMethodTest()
{
MockRepository mocks = new MockRepository();
ISomeInterface mockservice = mocks.StrictMock<ISomeInterface>();
using (mocks.Record())
{
mockservice.SomeMethod("xValue", "yValue");
LastCall.Constraints(Property.Value("x", "xValue"),
Property.Value("y", "yValue"));
}
mockservice.SomeMethod("xValue", "yValue");
mocks.Verify(mockservice);
}
}
Exception raised:
Rhino.Mocks.Exceptions.ExpectationViolationException : ISomeInterface.SomeMethod("xValue", "yValue"); Expected #0, Actual #1.
ISomeInterface.SomeMethod(property 'x' equal to xValue, property 'y' equal to yValue); Expected #1, Actual #0.
I would recommend you the following syntax (AAA syntax):
// arrange
var mockservice = MockRepository.GenerateMock<ISomeInterface>();
// act
mockservice.SomeMethod("xValue", "yValue");
// assert
mockservice.AssertWasCalled(
x => x.SomeMethod("xValue", "yValue")
);
This sample class illustrates the options for asserting methods were called with appropriate properties:
public class UsesThing
{
private IMyThing _thing;
public UsesThing(IMyThing thing)
{
_thing = thing;
}
public void DoTheThing(int myparm)
{
_thing.DoWork(myparm, Helper.GetParmString(myparm));
}
public void DoAnotherThing(int myparm)
{
AnotherThing thing2 = new AnotherThing();
thing2.MyProperty = myparm + 2;
_thing.DoMoreWork(thing2)
}
}
Using simple values for assertions may work for methods like the DoTheThing method which uses value types:
[Test]
public void TestDoTheThing()
{
IMyThing thing = MockRepository.GenerateMock<IMyThing>();
UsesThing user = new UsesThing(thing);
user.DoTheThing(1);
thing.AssertWasCalled(t => t.DoWork(1, "one");
}
However, if you need to create an object in your method and pass it as a parameter like in the DoAnotherThing method, this approach will not work since you will not have a reference to the object. You have to check the property values of the unknown object, like this:
[Test]
public void TestDoAnotherThing()
{
IMyThing thing = MockRepository.GenerateMock<IMyThing>();
UsesThing user = new UsesThing(thing);
user.DoAnotherThing(1);
thing.AssertWasCalled(t => t.DoMoreWork(null), t => t.IgnoreArguments().Constraints(Property.Value("MyProperty", 3))));
}
The new Rhino syntax would look like the following, but I am crashing VS 2008 when I use it:
thing.AssertWasCalled(t => t.DoMoreWork(Arg<AnotherThing>.Matches(Property.Value("MyProperty", 3))));