2012-04-18 6 views
8

mam szydzili metoda, która wygląda następująco:Wywoływanie Func przekazany jako parametr do mock wykorzystaniem Min i C#


class NotMineClass { 
    T Execute(Func operation) 
    { 
    // do something 
    return operation(); 
    } 
} 

W moim kodu, mam takie jak:


public MyType MyMethod() 
{ 
    MyType object = new MyType(); 
    bool success = notMineClassInstance.Execute(() => 
    { 
    // some things 
    retVal = injectedObject1.method(); 
    object.attribute = injectedObject2.method(); 
    // some other things 
    return retVal; 
    } 
    if (success) 
    { 
    object.otherAttribute = someValue; 
    } 
    return object; 
} 

My Przypadek jest, testuję MyMethod z Moq i chcę zweryfikować zachowanie Func zgodnie z oczekiwaniami. Mam kilka przedmiotów wstrzykniętych w jego ciało, które są drwinami i powinny być zweryfikowane; również zaczyna budować moją wartość zwracaną, więc nie mogę wykonać żadnego potwierdzenia, chyba że wywołam funkcję przekazaną jako parametr.

W Java i JUnit + EasyMock, chciałbym uchwycić parametr przekazany w następujący sposób:


public void testMyMethod() { 
    // ... 
    Capture < Function < void, Boolean > > functionCapture = Captures.last(); 
    expect(notMineClassInstance.execute(EasyMock.capture(functionCapture))); 
    // Expectations for the body of the function 

    replay(); 

    functionCapture.getValue().apply(null); 
} 

Jak mogę zrobić to samo przy użyciu C# + Min?

Odpowiedz

9

Można uchwycić argumentu wywołania kiedy dostarczyć Returns dla metody:

Mock<NotMineClassInstance> mock = new Mock<NotMineClassInstance>(); 
mock.Setup(x => x.Execute<bool>(It.IsAny<Func<bool>>())) 
    .Returns((Func<bool> captured) => { captured(); return true; }); 

Oto kompletny test na kodzie:

[Test] 
public void TestingSomething() 
{ 
    // Arrange 
    Mock<NotMineClassInstance> mockNotMine = new Mock<NotMineClassInstance>(); 
    mockDep.Setup(x => x.Execute<bool>(It.IsAny<Func<bool>>())).Returns((Func<bool> func) => func()); 

    Mock<Injected1> mockInjected1 = new Mock<Injected1>(); 
    mockInjected1.Setup(i => i.Method()).Returns(true); 

    Mock<Injected2> mockInjected2 = new Mock<Injected2>(); 
    mockInjected2.Setup(i => i.Method()).Returns("xxx"); 

    YourClass yourObject = new YourClass(mockDep.Object, mockInjected1.Object, mockInjected2.Object); 

    // Act 
    MyType my = yourObject.MyMethod();  

    // Assert 
    mockNotMine.Verify(d => d.Execute<bool>(It.IsAny<Func<bool>>())); 
    mockInjected1.Verify(i => i.Method()); 
    mockInjected2.Verify(i => i.Method()); 

    Assert.That(my.Attribute, Is.EqualTo("xxx")); 
    Assert.That(my.OtherAttribute, Is.EqualTo(someValue));    
} 

Również trzeba testu dla przypadku gdy mockInjected1.Method zwraca false.

+0

Wygląda świetnie, ale gdy to zrobię, pojawia się następujący błąd: * Test 'failed: System.NullReferenceException: Odwołanie do obiektu nie jest ustawione na instancję obiektu. w teście. b__0 (Uchwycony Funk'1) * –

+1

@ LuísGuilherme zobacz pełną próbkę testową –

+0

Działa od początku. Otrzymałem Null Reference w wywołaniu Func :) –