2014-04-18 10 views
11

Mam następujące klasy, która wykorzystuje wtrysk konstruktor:Jak wywołać konstruktora z argumentami interfejsu kiedy szyderczy konkretną klasę z Min

public class Service : IService 
{ 
    public Service(IRepository repository, IProvider provider) { ... } 
} 

Dla większości metod w tej klasie, po prostu stworzyć Min kpi dla IRepository i IProvider i skonstruować Service. Istnieje jednak jedna metoda w klasie, która wywołuje kilka innych metod w tej samej klasie. Aby przetestować tę metodę, zamiast testować wszystkie te metody razem, chcę przetestować, czy metoda wywołuje te metody poprawnie i poprawnie przetwarza ich wartości zwracane.

Najlepszym sposobem, aby to zrobić, aby drwić Service. Wyśmiewałem konkretne klasy z Moq, zanim nie miałem problemu. Nawet wyśmiewałem konkretne klasy, które wymagają argumentów konstruktora z Moq bez problemu. Jednakże, jest to pierwszy raz, kiedy musiał przejść szydzili argumenty do konstruktora dla wyśmiewali obiektu. Oczywiście próbowałem zrobić to w ten sposób:

var repository = new Mock<IRepository>(); 
var provider = new Mock<IProvider>(); 

var service = new Mock<Service>(repository.Object, provider.Object); 

To jednak nie działa. Zamiast tego pojawia się następujący błąd:

Castle.DynamicProxy.InvalidProxyConstructorArgumentsException : Can not instantiate proxy of class: My.Namespace.Service. 
Could not find a constructor that would match given arguments: 
    Castle.Proxies.IRepository 
    Castle.Proxies.IProvider 

Działa to dobrze, jeśli konstruktor Service „s wykonuje proste argumenty jak int s oraz string s, ale nie jeśli ma interfejsy, które mam szyderczy. Jak Ty to robisz?

+1

Którą wersję Moq i wersji zamkowej używasz? Ponieważ Twój przykładowy kod działa poprawnie przy użyciu Moq 4.2.1312.1622 i Castle.Core 3.2.2 ... – nemesv

Odpowiedz

4

miałem bardzo podobny problem, kiedy mój odpowiednik Service miał wewnętrzną konstruktora, więc to nie był widoczny dla Min.

dodałem

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] 

do mojego pliku AssemblyInfo.cs dla projektu wykonawczego. Nie jestem pewien, czy jest to istotne, ale chciałem dodać sugestię, że nie pomoże ci ani komuś innemu.

1

To musi być stara wersja problem, wszystko jest ok z najnowszej wersji. Nick, sprawdź!

P.s .: Zacząłem nagrodę od pomyłki (miałem błędny podpis w moim konstruktorze).

3

Czemu szydząc z serwisu są badania? Jeśli chcesz przetestować implementację klasy Service (bez względu na to, czy będzie to wywołanie wyśmiewanych obiektów, czy nie), potrzebujesz jedynie dwóch interfejsów, a nie klasy testowej.

Zamiast:

var repository = new Mock<IRepository>(); 
var provider = new Mock<IProvider>(); 

var service = new Mock<Service>(repository.Object, provider.Object); 

nie powinno być zamiast tego?

var repository = new Mock<IRepository>(); 
var provider = new Mock<IProvider>(); 

var service = new Service(repository.Object, provider.Object); 

Zdaję sobie sprawę, że jest to możliwemock konkretnych przedmiotów w pewnych ramach, ale jakie jest twoje przeznaczenie? Pomysł kpienia z czegoś polega na usunięciu faktycznej implementacji, aby nie wpłynęło to na twój test. Ale w swoim pytaniu stwierdziliście, że chcecie wiedzieć, że pewne klasy są prawidłowo wzywane, a następnie chcecie zatwierdzić wyniki tych działań. To niewątpliwie testowanie implementacji iz tego powodu trudno mi widzieć cele kpiny z konkretnego obiektu.

Powiązane problemy