Naprawdę doceniam zachowanie kpiące z Moq, które zwraca wartości domyślne, gdy nie są ustawione żadne oczekiwania. Jest to wygodne i zapisuje kod, a także działa jako środek bezpieczeństwa: zależności nie zostaną przypadkowo wywołane podczas testu urządzenia (o ile są wirtualne).Podczas kpiny z klasy z Moq, jak mogę CallBase dla tylko konkretnych metod?
Jestem jednak zdezorientowany, jak zachować te korzyści, gdy testowana metoda stanie się wirtualna.
W tym przypadku I do chce wywoływać prawdziwy kod dla tej jednej metody, a jeszcze luźno kpią z reszty klasy.
Wszystko, co znalazłem w moich poszukiwaniach, to że mogę ustawić mock.CallBase = true
, aby zapewnić wywołanie metody. Wpływa to jednak na całą klasę. Nie chcę tego robić, bo to stawia mnie w dylemat na temat wszystkich innych właściwości i metod klasy, które ukrywają zależności połączeń: jeśli CallBase prawda to mam albo
- odcinki instalacyjnych dla wszystkich właściwości i metody, które ukrywają zależności - mimo że mój test nie wymaga dbania o te zależności, lub
- Mam nadzieję, że nie zapomnę skonfigurować żadnych skrótów (i że żadne nowe zależności nie zostaną dodane do kod w przyszłości) - Testy jednostek ryzyka uderzają w prawdziwą zależność.
Co myślę, że chcę coś jak:
mock.Setup(m => m.VirtualMethod()).CallBase();
tak, że gdy zgłoszę mock.Object.VirtualMethod()
, Moq wzywa do rzeczywistej realizacji ...
Q: Z Min, czy jest jakiś sposób przetestować wirtualną metodę, gdy wyśmiewam się z klasy, żeby wyprowadzić kilka zależności? To znaczy. Bez odwoływania się do CallBase = true i konieczności stub wszystkich zależności?
przykład kod ilustrują
(używa MSTest, InternalsVisibleTo DynamicProxyGenAssembly2)
W poniższym przykładzie TestNonVirtualMethod
przejściach, ale nie TestVirtualMethod
- zwraca puste.
public class Foo
{
public string NonVirtualMethod() { return GetDependencyA(); }
public virtual string VirtualMethod() { return GetDependencyA();}
internal virtual string GetDependencyA() { return "! Hit REAL Dependency A !"; }
// [... Possibly many other dependencies ...]
internal virtual string GetDependencyN() { return "! Hit REAL Dependency N !"; }
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestNonVirtualMethod()
{
var mockFoo = new Mock<Foo>();
mockFoo.Setup(m => m.GetDependencyA()).Returns(expectedResultString);
string result = mockFoo.Object.NonVirtualMethod();
Assert.AreEqual(expectedResultString, result);
}
[TestMethod]
public void TestVirtualMethod() // Fails
{
var mockFoo = new Mock<Foo>();
mockFoo.Setup(m => m.GetDependencyA()).Returns(expectedResultString);
// (I don't want to setup GetDependencyB ... GetDependencyN here)
string result = mockFoo.Object.VirtualMethod();
Assert.AreEqual(expectedResultString, result);
}
string expectedResultString = "Hit mock dependency A - OK";
}
Wystarczy krótka z jakiego katalogu/moje potrzeby jest o: Need 'wersję CallBase' gdy szydząc, że zamiast * * "Wywołaj implementację klasy bazowej, jeśli żadne oczekiwania nie będą nadpisywać elementu" **, tak zwane _Partial Mocks_, po prostu wywołaj podstawową implementację wyśmianych członków! Chciałbym nazwać nową funkcję jako 'CallBaseOnMockedMemberOnly': D –