2015-03-24 1 views
-1

J'aime utiliser le comportement DefaultMock.Mock de Moq. Maintenant, j'ai le problème, que dans la hiérarchie des objets ainsi mocked un objet d'une classe abstraite sans un constructeur par défaut. Quand quelqu'un essaie maintenant d'obtenir cet objet, je reçois une exception. Existe-t-il un moyen de contourner ce problème?Hinder Moq pour simuler des classes abstraites sans constructeur par défaut?

Un court exemple:

//The abstract class 
public abstract class Abstract 
{ 
    protected Abstract(string foo) 
    { 
    } 
} 

//The mocked interface 
public interface ITestClass 
{ 
    Abstract Abstract { get; } 
} 

//The mock 
internal class TestClass 
{ 
    public static void Main() 
    { 
     Mock<ITestClass> testMock = new Mock<ITestClass> {DefaultValue = DefaultValue.Mock}; 
     Abstract foo = testMock.Object.Abstract; 
    } 
} 

Le problème se produit dans la ligne Abstract foo = testMock.Object.Abstract; l'exception est la suivante:

System.ArgumentException was unhandled 
    HResult=-2147024809 
    Message=Can not instantiate proxy of class: UsedLibrary.Abstract. 
Could not find a parameterless constructor. 
Parametername: constructorArguments 
    Source=Castle.Core 
    ParamName=constructorArguments 
+2

Il est difficile de comprendre ce que vous demandez. Pouvez-vous nous fournir un [Short, Self Contained, Correct, Compilable, Example] (http://sscce.org), s'il vous plaît? –

+1

Vous devez également inclure des détails sur l'exception. –

+0

Ajout d'un exemple – Yggdrasil

Répondre

1

solution devrait être quelque chose comme ceci:

Mock<ITestClass> testMock = new Mock<ITestClass> {DefaultValue = DefaultValue.Mock}; 
testMock.SetupGet(p => p.Abstract).Returns(new Abstract("foo")); 
Abstract foo = testMock.Object.Abstract; 

Mais PREMIER !!! Vous ne pouvez pas créer d'instance d'une classe abstraite, vous devez donc implémenter une classe dérivée d'une classe abstraite. Code devrait ressembler à:

testMock.SetupGet(p => p.Abstract).Returns(new InstanceWhichDerivesFromAbstract("foo")); 

Vous devez fournir une implémentation pour classe abstraite

public class InstanceWhichDerivesFromAbstract : Abstract 
{ 
//implementation 
} 
+1

Pourquoi ne pas simplement fournir une simulation de la classe abstraite et l'appeler un jour? Aussi, SetupGet ... sympa. – Will

+0

Je connais cette possibilité. La seule chose qui est vraiment ennuyante avec cette solution est que, dans l'exemple réel, l'objet abstrait est quelque part au troisième ou au quatrième niveau d'une hiérarchie mockée. C'est une douleur de le faire. – Yggdrasil