'Argument types do not match' is thrown for Struct but not for Class

9 posts, 0 answers
  1. Alex
    Alex avatar
    6 posts
    Member since:
    Aug 2012

    Posted 02 Aug 2012 Link to this post

    When mocking a property of _commandLineArgument struct, I get 'Argument types do not match' exception.
    When I make this struct a class(private class _commandLineArgument), everything works as expected.  Anybody can explain this behavior?  Anyway to make it work without making it a class.  Thank you.

    public abstract class ConsoleBase
    {
            private struct _commandLineArgument
            {
                public string Name { get; set; }
                public string Description { get; set; }
                public bool IsRequired { get; set; }
                public string Value { get; set; }
                public bool Found { get; set; }
            }
    }
     
    Type argType = Type.GetType( "Utilities.ConsoleBase+_commandLineArgument" );
    Mock.NonPublic.Arrange<bool>( argType, "Found" ).Returns(true);
  2. Alex
    Alex avatar
    6 posts
    Member since:
    Aug 2012

    Posted 03 Aug 2012 Link to this post

    Having tested more struct scenarios, it looks like there is no support for structs at all.  Even basic scenarios listed below don't work.  Does JustMock support struct mocking?
    Here's a simplified scenario that still doesn't work as is but works when struct is converted to a class:

    public struct commandLineArgument
    {
        public string Name { get; set; }
        public string Description { get; set; }
        public bool IsRequired { get; set; }
        public string Value { get; set; }
        public bool Found { get; set; }
    }
     
        [Test]
        public void Test()
        {
            commandLineArgument c = Mock.Create<commandLineArgument>();
            Mock.Arrange( () => c.Found ).Returns( true );
            Assert.IsTrue( c.Found );
        }
  3. DevCraft R3 2016 release webinar banner
  4. Ricky
    Admin
    Ricky avatar
    467 posts

    Posted 06 Aug 2012 Link to this post

    Hi Alex,

    Unfortunately, mocking members from struct is not working properly. However, we found the issue and will try our best to include a fix for it in the upcoming SP release.

    In the meantime, you can follow the task here:
    http://www.telerik.com/support/pits.aspx#/public/justmock/12182 


    Kind Regards
    Ricky
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  5. Alex
    Alex avatar
    6 posts
    Member since:
    Aug 2012

    Posted 06 Aug 2012 Link to this post

    When can we expect the next release and what is the chance of a fix being in the next release?  This is a big issue for us since structs are widely used in our code.  We need to make a 10-license purchasing decision very soon.  Thank you.
  6. Ricky
    Admin
    Ricky avatar
    467 posts

    Posted 09 Aug 2012 Link to this post

    Hi Alex,

    I have sent you an internal build in ticket #572988. Please check it out.

    Kind Regards
    Ricky
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  7. Alex
    Alex avatar
    6 posts
    Member since:
    Aug 2012

    Posted 13 Aug 2012 Link to this post

    This scenario now works:
    public struct commandLineArgument
    {
        public string Name { get; set; }
        public string Description { get; set; }
        public bool IsRequired { get; set; }
        public string Value { get; set; }
        public bool Found { get; set; }
    }
      
        [Test]
        public void Test()
        {
            commandLineArgument c = Mock.Create<commandLineArgument>();
            Mock.Arrange( () => c.Found ).Returns( true );
            Assert.IsTrue( c.Found );
        }

    But the original scenario still throws the "Argument types do not match" error:

    public abstract class ConsoleBase
    {
            private struct _commandLineArgument
            {
                public string Name { get; set; }
                public string Description { get; set; }
                public bool IsRequired { get; set; }
                public string Value { get; set; }
                public bool Found { get; set; }
            }
    }
      
    Type argType = Type.GetType( "Utilities.ConsoleBase+_commandLineArgument" );
    Mock.NonPublic.Arrange<bool>( argType, "Found" ).Returns(true);
    and if I do this:
    Type argType = Type.GetType( "Cmtm.Utilities.ConsoleBase+_commandLineArgument" );
    var ca = Mock.Create( argType, Constructor.NotMocked, Behavior.CallOriginal );
    Mock.NonPublic.Arrange<bool>( ca, "Found" ).Returns( true );

     I get "Attempt by method '_commandLineArgument_Interceptor_1d052085ba9c4ad3bc1b06c9b920f939.Intercept(System.String, _commandLineArgument, Boolean ByRef)' to access type 'Cmtm.Utilities.ConsoleBase+_commandLineArgument' failed."  When struct is used in the code being tested.
    Again both scenarios work when struct is made into a class.  Looks like nested structs are still not supported.

  8. Ricky
    Admin
    Ricky avatar
    467 posts

    Posted 16 Aug 2012 Link to this post

    Hi Alex,
    Thanks again for contacting us. However, this is not an issue with nested structure. I changed _commandLineArgument as public and it working as expected:

    ConsoleBase._commandLineArgument c = Mock.Create<ConsoleBase._commandLineArgument>();
    Mock.Arrange(() => c.Found).Returns(true);
    Assert.IsTrue(c.Found);

    After doing a bit more debugging, I found that you are trying to mock a non-static property as static. Therefore, I changed the test in the following way and now it is working as expected as well:

    [Test]
    public void Test()
    {
        Type argType = typeof(ConsoleBase).GetNestedType("_commandLineArgument");
     
        var target = Activator.CreateInstance(argType);
     
        Mock.NonPublic.Arrange<bool>(target, "Found").Returns(true);
     
        bool found = (bool)  argType.GetProperty("Found").GetValue(target, null);
     
        Assert.IsTrue(found);
    }

    Hope this solves your issue. I am using the latest Q2 2012 SP1 build.

    Kind Regards
    Mehfuz
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  9. Alex
    Alex avatar
    6 posts
    Member since:
    Aug 2012

    Posted 20 Aug 2012 Link to this post

    The sample you provided does work when struct is public, but the scenario that I am testing is exactly this:

    public abstract class ConsoleBase
    {
            private struct _commandLineArgument
            {
                public string Name { get; set; }
                public string Description { get; set; }
                public bool IsRequired { get; set; }
                public string Value { get; set; }
                public bool Found { get; set; }
            }
    }
    I need to test a method in the ConsoleBase class.  For my test to work, _commandLineArgument.Found property has to be mocked to return true.  I can not change access level of the struct to public.  And the sample you provided in the previous post does not work if struct is private.  Is there a way to accomplish the test that I am describing without modifying the code being tested?  Thank you.
  10. Ricky
    Admin
    Ricky avatar
    467 posts

    Posted 23 Aug 2012 Link to this post

    Hi Alex,

    Thanks again for contacting us. I got your point, however at present it is not possible to mock a member from nested private struct.

    However, we are investigating it and soon provide a solution.


    Kind Regards
    Ricky
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Back to Top
DevCraft R3 2016 release webinar banner