2012-06-30 21 views
16

Tôi đã có một vài trường hợp một cái gì đó như thế này sẽ hữu ích. Ví dụ: tôi có một số AccountCreator với phương thức Create mất NewAccount. My AccountCreatorIRepository mà cuối cùng sẽ được sử dụng để tạo tài khoản. AccountCreator của tôi trước tiên sẽ ánh xạ các thuộc tính từ NewAccount đến Account, giây vượt qua số Account để repo cuối cùng tạo ra nó. thử nghiệm của tôi giống như thế này:Làm thế nào để sử dụng moq để xác minh rằng một đối tượng tương tự đã được chuyển vào làm đối số?

public class when_creating_an_account 
{ 
    static Mock<IRepository> _mockedRepository; 
    static AccountCreator _accountCreator; 
    static NewAccount _newAccount; 
    static Account _result; 
    static Account _account; 

    Establish context =() => 
     { 
      _mockedRepository = new Mock<IRepository>(); 
      _accountCreator = new AccountCreator(_mockedRepository.Object); 

      _newAccount = new NewAccount(); 
      _account = new Account(); 

      _mockedRepository 
       .Setup(x => x.Create(Moq.It.IsAny<Account>())) 
       .Returns(_account); 
     }; 

    Because of =() => _result = _accountCreator.Create(_newAccount); 

    It should_create_the_account_in_the_repository =() => _result.ShouldEqual(_account); 
} 

Vì vậy, những gì tôi cần là một cái gì đó để thay thế It.IsAny<Account>, bởi vì điều đó không giúp tôi xác nhận rằng đúng Tài khoản đã được tạo ra. Điều gì sẽ là tuyệt vời là một cái gì đó giống như ...

public class when_creating_an_account 
{ 
    static Mock<IRepository> _mockedRepository; 
    static AccountCreator _accountCreator; 
    static NewAccount _newAccount; 
    static Account _result; 
    static Account _account; 

    Establish context =() => 
     { 
      _mockedRepository = new Mock<IRepository>(); 
      _accountCreator = new AccountCreator(_mockedRepository.Object); 

      _newAccount = new NewAccount 
       { 
        //full of populated properties 
       }; 
      _account = new Account 
       { 
        //matching properties to verify correct mapping 
       }; 

      _mockedRepository 
       .Setup(x => x.Create(Moq.It.IsLike<Account>(_account))) 
       .Returns(_account); 
     }; 

    Because of =() => _result = _accountCreator.Create(_newAccount); 

    It should_create_the_account_in_the_repository =() => _result.ShouldEqual(_account); 
} 

Thông báo tôi đã thay đổi It.IsAny<> để It.IsLike<> và thông qua trong một đối tượng dân cư Account. Lý tưởng nhất, trong nền, một cái gì đó sẽ so sánh các giá trị tài sản và để cho nó vượt qua nếu tất cả chúng phù hợp.

Vì vậy, nó đã tồn tại chưa? Hoặc có thể đây là điều bạn đã làm trước đây và không ngại chia sẻ mã?

+1

Moq hỗ trợ quẹt tùy chỉnh - như trong, bạn có thể có Người đối chiếu tùy chỉnh sử dụng khi phù hợp với lập luận cho một cuộc gọi , nhưng bạn phải tự mình thực hiện. Xem ví dụ [tại đây] (http://stackoverflow.com/a/10300051/343266). –

Trả lời

20

Để còn sơ khai ra một kho lưu trữ để trả về một giá trị cụ thể dựa trên các tiêu chí như thế nào, sau đây nên làm việc:

_repositoryStub 
    .Setup(x => x.Create(
     Moq.It.Is<Account>(a => _maskAccount.ToExpectedObject().Equals(a)))) 
    .Returns(_account); 
+0

Bây giờ, đó là những gì tôi đang tìm kiếm! Cảm ơn Derek! –

+3

Trong trường hợp bất cứ ai tình cờ gặp câu trả lời này và muốn thử cùng một điều, bạn phải đưa thư viện ExpectedObjects vào. https://github.com/derekgreer/expectedObjects hoặc 'install-package ExpectedObjects' –

12

Sau đây nên làm việc cho bạn:

Moq.It.Is<Account>(a=>a.Property1 == _account.Property1) 

Tuy nhiên vì nó đã được đề cập, bạn phải thực hiện các tiêu chí phù hợp.

+0

Tôi sử dụng nó mỗi ngày. Nhưng hãy tưởng tượng "a" là một lớp với 50 thuộc tính. Tôi thà có thể sử dụng mẫu đối tượng mong muốn để so sánh đối tượng thực tế (với tất cả các thuộc tính của nó) với một đối tượng mong muốn (với tất cả các thuộc tính mong đợi). Đó là những gì tôi đang nắm giữ. –

0

Tôi không thể tìm thấy bất kỳ thứ gì thực hiện chính xác những gì được mô tả trong câu hỏi. Trong thời gian đó, cách tốt nhất mà tôi có thể tìm thấy để xử lý xác minh đối tượng được truyền vào dưới dạng đối số cho phương thức giả (không có sự sang trọng bình đẳng giới thiệu) là kết hợp của Callback và mẫu Đối tượng dự kiến ​​để so sánh thực tế với đối tượng mong muốn:

public class when_creating_an_account 
{ 
    static Mock<IRepository> _mockedRepository; 
    static AccountCreator _accountCreator; 
    static NewAccount _newAccount; 
    static Account _result; 
    static Account _expectedAccount; 
    static Account _actualAccount; 

    Establish context =() => 
     { 
      _mockedRepository = new Mock<IRepository>(); 
      _accountCreator = new AccountCreator(_mockedRepository.Object); 

      _newAccount = new NewAccount 
       { 
        //full of populated properties 
       }; 
      _expectedAccount = new Account 
       { 
        //matching properties to verify correct mapping 
       }; 

      _mockedRepository 
       .Setup(x => x.Create(Moq.It.IsAny<Account>(_account))) 
       //here, we capture the actual account passed in. 
       .Callback<Account>(x=> _actualAccount = x) 
       .Returns(_account); 
     }; 

    Because of =() => _result = _accountCreator.Create(_newAccount); 

    It should_create_the_account_in_the_repository = 
     () => _result.ShouldEqual(_account); 

    It should_create_the_expected_account = 
     () => _expectedAccount.ToExpectedObject().ShouldEqual(_actualAccount); 
} 

Mẫu đối tượng mong muốn rất tuyệt vời, nhưng nó phức tạp để thực hiện trong C#, vì vậy tôi sử dụng thư viện xử lý tất cả mọi thứ cho tôi. https://github.com/derekgreer/expectedObjects

Quan sát cuối cùng của tôi xem xét các thuộc tính trong tài khoản thực tế được truyền vào và so sánh từng thuộc tính với cùng một "đối tượng mong đợi" của tôi. Bằng cách này tôi không có một danh sách lớn các kiểm tra tài sản giả, cũng không phải tôi có một tấn quan sát kiểm tra.

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