Menu

#21 Please add Generics Support

open
nobody
None
5
2008-05-06
2008-05-06
Anonymous
No

NMock2 fails hard with Interfaces that contain generic methods.

For example adding "X GenericMethod<X>();" to the IHelloWorld interface in the AcceptanceTests causes those tests to fail.

Discussion

  • David Schmitt

    David Schmitt - 2008-05-07

    Logged In: YES
    user_id=1439036
    Originator: NO

    I've now got a patch implementing a few tests and the neccessary changes in the MockObjectFactory that works for me.

    Index: src/NMock2/Monitoring/MockObjectFactory.cs

    RCS file: /cvsroot/nmock/nmock2/src/NMock2/Monitoring/MockObjectFactory.cs,v
    retrieving revision 1.2
    diff -u -r1.2 MockObjectFactory.cs
    --- src/NMock2/Monitoring/MockObjectFactory.cs 17 Jan 2008 18:48:22 -0000 1.2
    +++ src/NMock2/Monitoring/MockObjectFactory.cs 7 May 2008 07:33:32 -0000
    @@ -208,9 +208,29 @@
    method.CallingConvention,
    method.ReturnType,
    typeArray1);
    +#if NET20
    + if (method.IsGenericMethod)
    + {
    + // there surely must be a better way to do this.
    + // LINQ for example:
    + // (from info in method.GetGenericArguments() select info.Name).ToArray<string>()
    + Type[] genArgs = method.GetGenericArguments();
    + string[] genericNames = new string[genArgs.Length];
    + for (int num2 = 0; num2 < genArgs.Length; num2++)
    + {
    + genericNames[num2] = genArgs[num2].Name;
    + }
    + // end bad hack
    +
    + if (genericNames.Length > 0)
    + {
    + GenericTypeParameterBuilder[] typeParameters = builder1.DefineGenericParameters(genericNames);
    + }
    + }
    +#endif
    builder1.InitLocals = true;
    typeBuilder.DefineMethodOverride(builder1, method);
    return builder1.GetILGenerator();

    Index: src/NMock2.AcceptanceTests/MockeryAcceptanceTest.cs

    RCS file: /cvsroot/nmock/nmock2/src/NMock2.AcceptanceTests/MockeryAcceptanceTest.cs,v
    retrieving revision 1.5
    diff -u -r1.5 MockeryAcceptanceTest.cs
    --- src/NMock2.AcceptanceTests/MockeryAcceptanceTest.cs 20 Aug 2007 15:25:34 -0000 1.5
    +++ src/NMock2.AcceptanceTests/MockeryAcceptanceTest.cs 7 May 2008 07:33:32 -0000
    @@ -41,6 +41,178 @@

    Assert.AreSame(mockedType, container.GetService(typeof(IMockedType)));
    }
    +
    + public interface IEmpty { }
    +
    + [Test]
    + public void MockEmptyInterface()
    + {
    + Mockery mocks = new Mockery();
    + IEmpty mock = mocks.NewMock(typeof(IEmpty)) as IEmpty;
    + Assert.IsNotNull(mock);
    + }
    +
    + public interface INoArgs : IEmpty
    + {
    + void NoArgs();
    + int NoArgsReturnInt();
    + object NoArgsReturnObject();
    + }
    +
    + [Test]
    + public void MockSimpleInterface()
    + {
    + Mockery mocks = new Mockery();
    + INoArgs mock = mocks.NewMock(typeof(INoArgs)) as INoArgs;
    + Assert.IsNotNull(mock);
    + }
    +
    + public interface IArgs
    + {
    + void IntArg(int arg1);
    + int IntArgReturnInt(int arg1);
    + object ObjectArgsReturnObject(object arg1);
    + }
    +
    + [Test]
    + public void MockSimpleInterfaceWithArgs()
    + {
    + Mockery mocks = new Mockery();
    + IArgs mock = mocks.NewMock(typeof(IArgs)) as IArgs;
    + Assert.IsNotNull(mock);
    + }
    +
    +
    +#if NET20
    + public interface INoArgsGeneric<T>
    + {
    + void NoArgs();
    + T NoArgsReturnT();
    + }
    +
    + [Test]
    + public void MockSimpleGenericInterface()
    + {
    + Mockery mocks = new Mockery();
    + INoArgsGeneric<int> intMock = mocks.NewMock(typeof(INoArgsGeneric<int>)) as INoArgsGeneric<int>;
    + INoArgsGeneric<object> objectMock = mocks.NewMock(typeof(INoArgsGeneric<object>)) as INoArgsGeneric<object>;
    + Assert.IsNotNull(intMock);
    + Assert.IsNotNull(objectMock);
    + }
    +
    + public interface IArgsGeneric<T>
    + {
    + void TArg(T arg1);
    + T TArgReturnT(T arg1);
    + }
    +
    + [Test]
    + public void MockSimpleGenericInterfaceWithArgs()
    + {
    + Mockery mocks = new Mockery();
    + IArgsGeneric<int> intMock = mocks.NewMock(typeof(IArgsGeneric<int>)) as IArgsGeneric<int>;
    + IArgsGeneric<object> objectMock = mocks.NewMock(typeof(IArgsGeneric<object>)) as IArgsGeneric<object>;
    + Assert.IsNotNull(intMock);
    + Assert.IsNotNull(objectMock);
    + }
    +
    + public interface IArgsGenericFunction1
    + {
    + void TArg<T>(T arg1);
    + }
    +
    + public interface IArgsGenericFunction2
    + {
    + T ReturnT<T>();
    + }
    +
    + public interface IArgsGenericFunction3
    + {
    + T IntArgReturnT<T>(int args);
    + }
    +
    + public interface IArgsGenericFunction4
    + {
    + void MultiArg<A>(A a1, A a2, A a3);
    + }
    +
    + public interface IArgsGenericFunction5
    + {
    + void MultiArg<A, B, C, D, E, F>(A a, B b, C c, D d, E e, F f);
    + }
    +
    + public interface IArgsGenericFunction6
    + {
    + void MultiArg<A, B, C, D, E, F>(A a, int arg1, B b, bool arg2, C c, object arg3, D d, IEmpty arg4, E e, IArgsGeneric<F> arg5, F f);
    + }
    +
    + [Test]
    + public void MockGenericInterfaceWithArgs1()
    + {
    + Mockery mocks = new Mockery();
    + IArgsGenericFunction1 mock1 = mocks.NewMock(typeof(IArgsGenericFunction1)) as IArgsGenericFunction1;
    + Assert.IsNotNull(mock1);
    + }
    +
    + [Test]
    + public void MockGenericInterfaceWithArgs2()
    + {
    + Mockery mocks = new Mockery();
    + IArgsGenericFunction2 mock2 = mocks.NewMock(typeof(IArgsGenericFunction2)) as IArgsGenericFunction2;
    + Assert.IsNotNull(mock2);
    + }
    +
    + [Test]
    + public void MockGenericInterfaceWithArgs3()
    + {
    + Mockery mocks = new Mockery();
    + IArgsGenericFunction3 mock3 = mocks.NewMock(typeof(IArgsGenericFunction3)) as IArgsGenericFunction3;
    + Assert.IsNotNull(mock3);
    + }
    +
    + [Test]
    + public void MockGenericInterfaceWithArgs4()
    + {
    + Mockery mocks = new Mockery();
    + IArgsGenericFunction4 mock4 = mocks.NewMock(typeof(IArgsGenericFunction4)) as IArgsGenericFunction4;
    + Assert.IsNotNull(mock4);
    + }
    +
    + [Test]
    + public void MockGenericInterfaceWithArgs5()
    + {
    + Mockery mocks = new Mockery();
    + IArgsGenericFunction5 mock5 = mocks.NewMock(typeof(IArgsGenericFunction5)) as IArgsGenericFunction5;
    + Assert.IsNotNull(mock5);
    + }
    +
    + [Test]
    + public void MockGenericInterfaceWithArgs6()
    + {
    + Mockery mocks = new Mockery();
    + IArgsGenericFunction6 mock6 = mocks.NewMock(typeof(IArgsGenericFunction6)) as IArgsGenericFunction6;
    + Assert.IsNotNull(mock6);
    + }
    +
    + public interface IMixed<X>
    + where X : IEmpty
    + {
    + void TArg<T>(T arg1, X arg2);
    + T ReturnT<T>(X arg2);
    + T IntArgReturnT<T>(int arg1, X arg2);
    + X ReturnX<T>(T arg2);
    + }
    +
    + [Test]
    + public void MockMixedInterface()
    + {
    + Mockery mocks = new Mockery();
    + IMixed<IEmpty> emptyMock = mocks.NewMock(typeof(IMixed<IEmpty>)) as IMixed<IEmpty>;
    + IMixed<INoArgs> inheritMock = mocks.NewMock(typeof(IMixed<INoArgs>)) as IMixed<INoArgs>;
    + Assert.IsNotNull(emptyMock);
    + Assert.IsNotNull(inheritMock);
    + }
    +#endif
    }

    public interface IMockedType

     
  • Thomas Weingartner

    Logged In: YES
    user_id=1140914
    Originator: NO

    Thanx for your input David. Have a look at NMock2 (http://nmock2.sourceforge.net). We already support Generics.

    Cheers
    Thomas

     

Log in to post a comment.