See simple code below of ClassToTest with two public constructors with one parameter. My favorite mocking framework (Rhino Mocks) is unable to determine which constructor to use for mocking. The CreatePartialMock method throws an AmbiguousMatchException.
public interface IParam1 { string Name { get; } } public interface IParam2 { string Name { get; } } public class ClassToTest { private ClassToTest() { } // Mocking framework is unable to determine which // constructor to use, because both have one parameter public ClassToTest(IParam1 param) { Name = param != null ? param.Name : string.Empty; } public ClassToTest(IParam2 param) { Name = param != null ? param.Name : string.Empty; } public virtual string Name { get; private set; } }
The workaround for this is to create an extra layer of inheritance. The new class makes the choice for the mocking framework by specifying the base constructor. See the code below.
[TestClass] public class UnitTest { /// <summary> /// Mockable Class To Test /// </summary> /// <remarks> /// Has only the default constructor and will not throw the /// AmbiguousMatchException when mocked /// </remarks> public class MockableClassToTest : ClassToTest { /// <summary> /// For Mocking of ClassToTest purposes only /// <summary> public MockableClassToTest() : base(default(IParam1)) { } } /// <summary> /// Creating the Mock fails with AmbiguousMatchException, /// because ClassToTest has two constructors with one parameter /// </summary> [TestMethod] [ExpectedException(typeof(System.Reflection.AmbiguousMatchException))] public void ConstructorFailsWithAmbiguousMatchException() { // System.Reflection.AmbiguousMatchException: Ambiguous match found. var testObject = MockRepository.GeneratePartialMock<ClassToTest>(default(IParam1)); } /// <summary> /// Create Mock with MockableClassToTest and set the /// Name of the Mock with an Expect /// </summary> [TestMethod] public void GetNameFromMock() { // arrange var testObject = MockRepository.GeneratePartialMock<MockableClassToTest>(); testObject.Expect(x => x.Name).Return("Correct"); Assert.IsNotNull(testObject); // act var actual = testObject.Name; // assert Assert.AreEqual<string>("Correct", actual); } }
The UnitTestclass above can be run to reproduce the situation. Make sure to include the ClassToTest from the top of this post.