This is a migrated thread and some comments may be shown as answers.

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

8 Answers 333 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Alex
Top achievements
Rank 1
Alex asked on 03 Aug 2012, 01:08 AM
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);

8 Answers, 1 is accepted

Sort by
0
Alex
Top achievements
Rank 1
answered on 03 Aug 2012, 10:56 PM
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 );
    }
0
Ricky
Telerik team
answered on 06 Aug 2012, 06:26 PM
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.

0
Alex
Top achievements
Rank 1
answered on 06 Aug 2012, 07:16 PM
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.
0
Ricky
Telerik team
answered on 09 Aug 2012, 03:49 PM
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.

0
Alex
Top achievements
Rank 1
answered on 13 Aug 2012, 07:06 PM
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.

0
Ricky
Telerik team
answered on 16 Aug 2012, 10:18 PM
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.

0
Alex
Top achievements
Rank 1
answered on 20 Aug 2012, 11:55 PM
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.
0
Ricky
Telerik team
answered on 23 Aug 2012, 08:13 PM
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.

Tags
General Discussions
Asked by
Alex
Top achievements
Rank 1
Answers by
Alex
Top achievements
Rank 1
Ricky
Telerik team
Share this question
or