chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
0 votes
Hi,

I'm struggling to basically fake a return from a property that is contained in a public class, with an internal private class.

Whatever I try I can't get it to work. Here's the class:

namespace SixPack.Data
{
        /// <summary>
        /// This class is used to wrap and execute stored procedures.
        /// </summary>
        public class StoredProcedure : IDisposable
        {

                private class ConnectionInfo
                {
                        private readonly string connectionString;

                        /// <summary>
                        /// Gets the connection string.
                        /// </summary>
                        /// <value>The connection string.</value>
                        public string ConnectionString
                        {
                                get
                                {
                                        return connectionString;
                                }
                        }


I'm trying to fake the ConnectionString property, as I don't want the test to rely on config files etc. I'd have thought this would be easy enough to do, so this is what I've tried :

var myType = Type.GetType("SixPack.Data.StoredProcedure+ConnectionInfo, SixPack, Version=1.1.1.0, Culture=neutral, PublicKeyToken=d2a7cc6ee67de205");

Isolate.NonPublic.Property.WhenGetCalled(myType,"ConnectionString").WillReturn("astring");



And here's the error I get :

*** Failures ***
Execute
TypeMock.TypeMockException:
*** No get property with name ConnectionString in type SixPack.Data.StoredProcedure+ConnectionInfo exists.
at ht.b(Type A_0, String A_1, ir A_2, Boolean A_3)
at g4.b(Type A_0, String A_1)
at xxxx(Boolean deleteOldMessages, Int32 daysOld, Int32 incompleteTimeout) in xxxx.cs:line 53
at TypeMock.MockManager.a(String A_0, String A_1, Object A_2, Object A_3, Boolean A_4, Boolean A_5, Object[] A_6)
at TypeMock.InternalMockManager.getReturn(Object that, String typeName, String methodName, Object methodParameters, Boolean isInjected, Boolean isInterceptedType, Object p1, Object p2, Object p3)
at xxxx(Boolean deleteOldMessages, Int32 daysOld, Int32 incompleteTimeout) in xxxx.cs:line 36
### Step FetchUtmMessagesToProcess_Call_ReturnProc: failed ###


Any ideas as I'm stumped now? It's version 6.0.4 - they're quite behind I'm afraid.

Thanks in advance,
Tony
asked by boltonto (1.8k points)

3 Answers

0 votes
Hi,

Assuming that you instantiate the nested class at some point in order to call its property( as I did in publicConectionString() )

public class StoredProcedure
{
    private class ConnectionInfo
    {
        private readonly string connectionString;

        public string ConnectionString
        {
            get { return connectionString; }
        }
    }

    public string publicConectionString()
    {
        var CInfo =  new ConnectionInfo();

        return CInfo.ConnectionString;
    }
}


A possible test for this issue can be written with the use of our old API the following way:

namespace boltonto
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            //obtain the Nested Type
            var myType = typeof (StoredProcedure);
            var nestedType = myType.GetNestedType("ConnectionInfo", BindingFlags.Instance | BindingFlags.NonPublic);

            //fake the nested type
            Mock mock = MockManager.Mock(nestedType);

            //set expectation on the get method of the ConnectionString property
            mock.ExpectGet("ConnectionString", "astring");

            var st = new StoredProcedure();
            Assert.AreEqual("astring", st.publicConectionString());
        }
    }
}


MockManager.Mock(nestedType); not only creates a fake object, but also swaps a all future instances of nestedType with the fake object.
This is parallel to Isolate.fake.Instance + Isloate.Swap.NextInstance in the new API.

*Note that mixing the new API with the old one in the same test is not allowed in most cases because it might cause unexpected behavior.

Please let me know if it helps.
answered by alex (17k points)
0 votes
Thanks Alex that's brilliant - I'll give it a try when I get in tomorrow.

Incidentally why doesn't the new API accommodate this kind of thing?

Thanks again,
Tony
answered by boltonto (1.8k points)
0 votes
Hi Toni,

I think that this feature was left out because there was no demand for it.
answered by alex (17k points)
...