2016-08-04 27 views
5

Ich habe zwei Klassen wie dieseeine abstrakte Klasse Mocking von einer abstrakten Klasse abgeleitete

public abstract class Foo<T> where T : Bar { 
    public Bar Do(Bar obj) { 
    //I cast to T here and the call the protected one. 
    } 
    ... 
    protected abstract Bar Do(T obj); 
} 

public abstract class FooWithGoo<T> : Foo<T> where T:Bar { 
    ... 
} 

Den Versuch, dies in einem Unit-Test zu verspotten mit Moq mit dieser Linie new Mock<FooWithGoo<Bar>>() gibt mir diese Ausnahme.

System.ArgumentException: Type to mock must be an interface or an abstract or non-sealed class. ---> System.TypeLoadException: Method 'Do' in type 'Castle.Proxies.FooWithGoo``1Proxy' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.

Gibt es etwas, was ich hier falsch mache? Wie kann ich das verspotten?

UPDATE: Dies zeigt das Problem gut für mich.

using Microsoft.VisualStudio.TestTools.UnitTesting; 
using Moq; 
namespace UnitTestProject1 
{ 

public class Bar 
{ 

} 

public class BarSub : Bar 
{ 

} 

public abstract class Foo<T> where T : Bar 
{ 
    public Bar Do(Bar obj) 
    { 
     return null; 
    } 
    protected abstract Bar Do(T obj); 
} 

public abstract class FooWithGoo<T> : Foo<T> where T : Bar 
{ 
    public FooWithGoo(string x) 
    { 

    } 
} 

[TestClass] 
public class UnitTest1 
{ 
    [TestMethod] 
    public void TestMethod1() 
    { 
     var mock = new Mock<FooWithGoo<Bar>>("abc"); 
     FooWithGoo<Bar> foo = mock.Object; 
    } 

    [TestMethod] 
    public void TestMethod2() 
    { 
     var mock = new Mock<FooWithGoo<BarSub>>("abc"); 
     FooWithGoo<BarSub> foo = mock.Object; 
    } 
} 
} 

Test1 schlägt fehl, während Test 2 besteht. Das Problem ist, dass das generische Abstract die gleiche Signatur bekommt wie die konkrete Methode ... und es wird dadurch verwirrt, denke ich.

+0

Ich kann das jetzt reproduzieren. Deine Vermutung scheint mir gut zu sein. – tster

Antwort

0

Ich konnte Ihr Problem mit dem bereitgestellten Beispiel reproduzieren.

Ich habe TestMethod1 übergeben, indem Sie Do eine virtuelle Methode machen.

Moq benötigt öffentliche Methoden, um entweder virtuell oder abstrakt zu sein, um ihre Implementierung zu verspotten.