2012-05-05 24 views
10

Nói rằng tôi có như sau:Làm thế nào để thử một phương pháp gọi mà phải mất một đối tượng năng động

public interface ISession 
{ 
    T Get<T>(dynamic filter); } 
} 

Và tôi đã đoạn mã sau mà tôi muốn thử nghiệm:

var user1 = session.Get<User>(new {Name = "test 1"}); 
var user2 = session.Get<User>(new {Name = "test 2"}); 

Làm thế nào tôi sẽ nhạo báng cuộc gọi này?

Sử dụng Moq, tôi mệt mỏi làm điều này:

var sessionMock = new Mock<ISession>(); 
sessionMock.Setup(x => x.Get<User>(new {Name = "test 1")).Returns(new User{Id = 1}); 
sessionMock.Setup(x => x.Get<User>(new {Name = "test 1")).Returns(new User{Id = 2}); 

Và điều đó không làm việc. Các kết quả trả về là null

Tôi cũng đã cố gắng để làm như sau với Rhino Mocks:

var session = MockRepository.GenerateStub<ISession>(); 
session.Stub(x => x.Get<User>(new {Name = "test 1"})).Return(new User{Id=1}); 

Không may mắn trong hai. Null một lần nữa.

Vậy tôi sẽ làm điều này như thế nào?

Cảm ơn,

Trả lời

22

On giải pháp là sử dụng It.Is<object> khớp cùng với sự phản ánh. Bạn không thể sử dụng động trong cây biểu hiện rất It.Is<dynamic> sẽ không làm việc đó là lý do tại sao bạn cần phải suy nghĩ để có được giá trị tài sản của bạn bằng tên:

sessionMock 
    .Setup(x => x.Get<User>(
     It.Is<object>(d => d.GetPropertyValue<string>("Name") == "test 1"))) 
    .Returns(new User{Id = 1}); 
sessionMock 
    .Setup(x => x.Get<User>(
     It.Is<object>(d => d.GetPropertyValue<string>("Name") == "test 2"))) 
    .Returns(new User { Id = 2 }); 

đâu GetPropertyValue là một chút helper:

public static class ReflectionExtensions 
{ 
    public static T GetPropertyValue<T>(this object obj, string propertyName) 
    { 
     return (T) obj.GetType().GetProperty(propertyName).GetValue(obj, null); 
    } 
} 
+0

Hoàn hảo! Chính xác những gì tôi cần. Cảm ơn bạn! –

0

Moq cung cấp It.IsAny<T> cho trường hợp đó

sessionMock.Setup(x => x.Get<User>(It.IsAny<object>()).Returns(new User()); 

* năng động là bất kỳ đối tượng

+1

Cảm ơn ai.farfa. Tôi không thể làm điều đó bởi vì tôi cần nói cho đối tượng nào trả về dựa trên các thuộc tính khác nhau trên đối tượng động –

1

Trước tất cả, các đối tượng ẩn danh không thực sự là dynamic.

Nếu bạn sử dụng dynamic đối tượng như

dynamic user1Filter = new ExpandoObject(); 
user1Filter.Name = "test 1"; 
var user1 = session.Get<User>(user1Filter); 

bạn có thể thử nó như

sessionMock.Setup(x => x.Get<User>(DynamicFilter.HasName("test 1"))); 

bằng cách thực hiện lập luận tùy chỉnh khớp:

static class DynamicFilter 
{ 
    [Matcher] public static object HasName(string name) { return null; } 
    public static bool HasName(dynamic filter, string name) 
    { 
     string passedName = filter.Name; //dynamic expression 
     return name.Equals(passedName); 
    } 
} 
Các vấn đề liên quan