2012-04-18 22 views
8

Tôi có một phương pháp chế giễu đó trông như thế này:Gọi Func trôi qua như một tham số để một mô hình sử dụng Moq và C#


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

Trong mã của tôi, tôi làm như:


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 trường hợp là, tôi đang thử nghiệm MyMethod với Moq và tôi muốn xác minh hành vi Func như mong đợi. Tôi có một số đối tượng tiêm trong cơ thể của nó, đó là mocks, và cần được xác minh; nó cũng bắt đầu xây dựng giá trị trả về của tôi, vì vậy tôi không thể thực hiện bất kỳ xác nhận nào trừ khi tôi gọi hàm được chuyển thành tham số.

Trong Java và JUnit + EasyMock, tôi sẽ nắm bắt thông số trôi qua, như thế này:


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

Làm thế nào để làm điều tương tự bằng C# + Moq?

Trả lời

9

Bạn có thể chụp luận gọi khi cung cấp Returns cho phương pháp:

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

Đây là thử nghiệm hoàn chỉnh cho mã của bạn:

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

Ngoài ra bạn cần kiểm tra đối với trường hợp khi mockInjected1.Method trả về false.

+0

Có vẻ tuyệt vời, nhưng khi tôi làm điều này, tôi nhận được lỗi sau: * Kiểm tra 'không thành công: System.NullReferenceException: Tham chiếu đối tượng không được đặt thành phiên bản của đối tượng. tại Test. b__0 (Func'1 bị bắt) * –

+1

@ LuísGuilherme xem mẫu thử hoàn chỉnh –

+0

Nó hoạt động ngay từ đầu. Tôi đã nhận được một tham chiếu Null bên trong cuộc gọi Func :) –

Các vấn đề liên quan