2016-08-04 31 views
5

mam dwie klasy jak tenMocking abstrakcyjną klasę pochodną od klasy abstrakcyjnej

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 { 
    ... 
} 

Próbując mock to w badanej jednostki przy użyciu MOQ z tej linii new Mock<FooWithGoo<Bar>>() daje mi ten wyjątek.

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.

Czy coś robię źle tutaj? Jak mogę to udawać?

AKTUALIZACJA: To pokazuje ładnie dla mnie problem.

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; 
    } 
} 
} 

Test 1 kończy się niepowodzeniem, gdy test 2 przechodzi. Problem polega na tym, że ogólne streszczenie dostaje ten sam podpis niż konkretna metoda ... i to się myli, tak myślę.

+0

Mogę odtworzyć to teraz. Twoje przypuszczenie wydaje mi się rozsądne. – tster

Odpowiedz

0

Udało mi się odtworzyć problem z podanym przykładem.

Mam przejść przez wprowadzenie Do wirtualnej metody.

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

Moq wymaga, aby metody publiczne były albo wirtualne, albo abstrakcyjne, aby móc kpić z ich implementacji.