Operation Parameters

Options
Bill Belanger
edited October 2011 in Photon Server
When are RequestParameter properties parsed by an Operation? I'm trying to write a unit test to verify that my operation params are being parsed but it keeps failing. Is there a function that needs to be called to parse the parameters out of the operation request? I'm using Moq as my mocking framework - which is used for the IRpcProtocol.

Simplified Operation Class
public class MyOperation : LiteOperation
{
  public MyOperation(OperationRequest req) : base(req){}
  [RequestParameter(Code = 247, IsOptional = false)]
  public long Param { get; set; }
}

Unit Test
public void TestMethod()
{
  IRpcProtocol protocol = new Mock<IRpcProtocol>().Object;
  long expected = 5;
  short opCode = 142;
  short p1 = 247;
  OperationRequest req = new OperationRequest(
    protocol, opCode, new Dictionary<short, object>{{p1, expected}}, Reliability.Reliable, 0, 0);
  MyOperation target = new MyOperation(req);
  Assert.AreEqual(expected, target.Param);
}

Comments

  • Boris
    Options
    The IRpcProtocol has ONE method that is important for the mapping, which is "TryConvertOperationParameter". This method has to return true to get it working.
    The operation class has an "IsValid" property and a "GetErrorMessage()" method, add "Assert.IsTrue(target.IsValid, target.GetErrorMessage());" before your last line to ensure that the mapping succeeded.

    Having said this I am wondering which version of Photon you are using:
    RequestParameter is Photon 2, but the existence of class LiteOperation indicates that it's not the latest version.
    You should probably update if you can.
  • Thanks for your response.

    I'm working on an existing application, attempting to write unit tests (which were pushed to the side in favour of time) so that when we do upgrade to Photon 3 we can quickly identify what needs to be updated.

    I'll look into those methods later today.
  • Answer is found (again, keep in mind this is using the Moq framework, individual mocking framework implementations may differ)

    I'm aware that this will only work for a single input parameter at the moment. I'm going to look into modifying this to be more specific on the TryConverOperationParameter call for multiple input parameters.
    public void TestMethod()
    {
      object obj = 5L;
      short opCode = 142;
      short p1 = 247;
      Mock<IRpcProtocol> mockProtocol = new Mock<IRpcProtocol>();
      mockProtocol.Setup(mock => mock.TryCOnvertOperationParameter(
        It.IsAny<ObjectMemberInfo<RequestParameterAttribute>>(), ref obj))
        .Returns(true);
      OperationRequest operationRequest = new OperationRequest(
        mockProtocol.Object, opCode, new Dictionary<short, object>{ {p1, obj} }, Reliability.Reliable, 0 0);
      MyOperation target = new MyOperation(operationRequest);
      Assert.IsNotNull(target);
      Assert.AreEqual(obj, target.Param);
      Assert.IsTrue(target.IsValid, target.GetErrorMessage());
    }
    
  • Had a lightbulb moment immediately after posting my answer.
    mockProtocol.Setup(mock => mock.TryConvertOperationParameter(
      It.Is<ObjectMemberInfo<RequestParameterAttribute>>(memberinfo => memberinfo.MemberAttribute.Code == p1), ref obj))
    .Returns(true)
    
  • Boris
    Options
    TryConvertOperationParameter just checks if the type of the param needs to be converted, it returns false if the input object cannot be assigned to the target property.
    For instance, if the property is a Guid and the input object is a byte array this would usually not work. However, the GpBinary implementation of IRpcProtocol converts a byte array of length 16 to a Guid and then returns true. If the input object is an integer it returns false.
    The IsValid property is then false and GetErrorMessage contains a debug message that tells you which parameter failed.