2013-07-09 145 views
0

即時通訊使用.net mvc3構建簡單的應用程序。我寫了幾個測試用例,我遇到了其中一個問題。即時通訊使用起訂量來嘲笑我的域名服務,我有這個兩個方法:模擬方法不會返回對象

List<Customer> customersRepo = 
{ 
    new Customer{ 
    Id = 0, 
    Name = "Jojo" 
    }, 
    new Customer{ 
    Id = 1, 
    Name = "John" 
    } 
} 

mock.Setup(m => m.GetByName(IsAny<string>())).Returns<string>(
n => 
customersRepo.Where(c => c.Name == n) 
); 

mock.Setup(m => m.GetById(IsAny<int>())).Returns<int>(
    n=> 
    customersRepo.Where(c => c.Id == n) 
); 

的問題是,當我使用模擬對象的方法,通過名字來獲取客戶的我得到一個我問了,但是當我嘗試以ID獲取我總是從模擬對象中獲得空對象..我試圖與ID 0和1 ..可能是什麼問題?

感謝

+1

我不能相信這些設置按預期工作。這兩個設置都返回一個'IEnumerable ',但一個表示它返回一個'string',另一個表示它返回一個'int'。這兩者都不是'IEnumerable '。 –

回答

1

我覺得你應該返回第一個或默認的客戶:

mock.Setup(m => m.GetById(IsAny<int>())).Returns<int>(
    id => 
    customersRepo.FirstOrDefault(c => c.Id == id) 
); 

也請記住,你並不需要在嘲笑重新實現資源庫的邏輯(即怪異非常脆弱)。這是模擬。你可以嘲笑任何你想要的結果,沒有任何邏輯:

mock.Setup(m => m.GetById(42)).Returns<int>(new Customer { Id = 42 }); 

使用嘲笑驗證互動 - 即你的資料庫被稱爲預計法預計參數的客戶。


如果你想測試一些服務的業務邏輯,那麼服務是一個被測系統(SUT),你不應該嘲笑它。但是,如果你的服務同時具有業務邏輯和數據訪問邏輯,那麼它做的事情太多了。提取數據訪問邏輯一些倉庫類,它將實現接口:

public interface ICustomerRepository 
{ 
    Customer GetById(int id); 
    // other methods related to customr data access 
} 

然後,讓你的服務依賴於該接口上(依賴倒​​置):

public class YourService 
{ 
    private readonly ICustomerRepository _repository; 
    // dependency injection 
    public YourService(ICustomerRepository repository) 
    { 
     _repository = repository; 
    } 

    public void ExecuteSomeBusinessLogic() 
    { 
     // your code will go here 
    } 
} 

然後寫服務的測試。因此,服務需要依賴性(客戶存儲庫),你應該嘲笑這種依賴性。並按照您的預期驗證服務與依賴關係進行交互。例如。在ExecuteSomeBusinessLogic測試中,我們應該檢查該服務會詢問顧客,ID爲42(是的,怪異的業務邏輯):

[Test] 
public void ShouldPerformGoodStuffWhenCustomerFound() 
{ 
    // Arrange 
    var mockRepository = new Mock<ICustomerRepository>(); 
    mockRepository.Setup(r => r.GetById(42)).Returns(new Customer { Id = 42 }); 
    var service = new YourService(mockRepository.Object); 
    // Act 
    service.ExecuteSomeBusinessLogic(); 
    // Assert 
    mockRepository.VerifyAll(); 
    // check other stuff 
} 

如果你寫的情況下測試時,沒有在數據庫中找到自定義,只安裝不同的回報:

mockRepository.Setup(r => r.GetById(42)).Returns(null); 
+0

我已經在LINQ結束時嘗試了FirstOrDefault(),這也不是我的存儲庫邏輯在這裏..我只是模擬數據存儲作爲列表,並有少量記錄..然後我嘲笑我的客戶服務,以便進行單元測試。然而,我會改變這樣做的方式,我會添加新用戶(準備測試),然後生病嘗試使用該方法) – stefo0O0o

+0

mock.Setup(m => m.GetCustomerById(It.IsAny ()) ).Returns ( id => customersRepo.FirstOrDefault(c => c.Id == id) ); – stefo0O0o

+0

這是什麼意思返回,我在互聯網上看到,返回中的泛型類型實際上是我想要在模擬方法內部接收的參數的類型,所以我可以根據該參數採取行動,即int是實際的id當我在模擬對象上調用GetById方法時發送的。 – stefo0O0o

0

我其實只是改了一下我的基礎設施..現在我的服務中獲得的DataSource接口對象在構造函數中..這是獨立的數據源,並依靠它來獲得客戶對象,OFC。在它檢查業務規則並執行任何需要的用戶輸入清潔之後。現在,我將在單元測試中嘲笑我的數據源(一個包含客戶對象的列表),並使用此嘲笑的回購爲我的服務提供一個實例的客戶對象..這樣我可以測試我已經編碼的服務業務邏輯的正確性。之前我已經將該服務與特定的數據存儲(即使用EF DbContext的數據庫)相結合,並且在單元測試中使用該服務有點困難,因爲它已經與數據庫耦合了,但我不想更改和恢復db狀態只是爲了執行我的單元測試,所以我想用簡單的客戶對象列表來模擬數據存儲。感謝您的努力,幫助我在那裏:)

相關問題