2014-12-04 31 views
2

我有一個MVC4 web應用程序,現在我正在進行單元測試。它使用數據庫部分的實體框架。我使用NSubstitute來模擬數據庫。這段代碼基本上是從另一個可以正常工作的網站上覆制粘貼的,所以我希望我只是錯過了一些超級簡單的東西。MVC4單元測試NSubstitute找不到調用返回

在此先感謝!

申請表中的SQL:

AppID | ApplicationName 
---------------------------- 
1  | MyCoolApplication 
2  | MyOtherApplication 

實體創建的應用程序類:

public class Application 
{ 
    public int AppID { get; set; } 
    public string ApplicationName { get; set; } 
} 

單元測試的模擬部分看起來是這樣的:

var mockDb = Substitute.For<MyCoolApplicationsEntities>(); 

var applications = new List<Application> 
{ 
    new Application {AppID = 1, ApplicationName = "MyCoolApplication"}, 
    new Application {AppID = 2, ApplicationName = "MyOtherApplication"}, 
}; 

var mockApplicationSet = Substitute.For<IDbSet<Application>, DbSet<Application>>(); 
mockApplicationSet.Provider.Returns(applications.AsQueryable().Provider); 
mockApplicationSet.Expression.Returns(applications.AsQueryable().Expression); 
mockApplicationSet.ElementType.Returns(applications.AsQueryable().ElementType); 
mockApplicationSet.GetEnumerator().Returns(applications.AsQueryable().GetEnumerator()); 

mockApplicationSet.When(q => q.Add(Arg.Any<Application>())) 
    .Do(q => applications.Add(q.Arg<Application>())); 

mockApplicationSet.When(q => q.Remove(Arg.Any<Application>())) 
    .Do(q => applications.Remove(q.Arg<Application>())); 


mockDb.Applications.Returns(mockApplicationSet); //This is the line creating the error 

完整的錯誤是:

試驗方法 MyProjectName.Controllers.MyControllerTest.TestOfSectionImTesting 拋出異常: NSubstitute.Exceptions.CouldNotSetReturnDueToNoLastCallException: 找不到一個電話從返回。

確保你叫返回()調用你的替代品(之後 例如:mySub.SomeMethod()返回(值)),以及你是返回()(例如內不 配置其他替代品,避免 this:mySub.SomeMethod()。Returns(ConfigOtherSub()))。

如果您替換類而不是接口,請檢查對替代者的調用是否在虛擬/抽象成員上。返回 無法爲非虛擬/非抽象成員配置值。

正確的使用方法:

mySub.SomeMethod().Returns(returnValue); 

潛在問題的用途:

mySub.SomeMethod().Returns(ConfigOtherSub()); 

而是嘗試:

var returnValue = ConfigOtherSub(); 

mySub.SomeMethod().Returns(returnValue); 

但是,這並不在我的環境中工作,因爲應用程序的ISN」一種方法。就像我說過的,這在我的另一個網站中工作正常,所以它必須是基本的東西,我失蹤了。我在網上找到的任何東西都對我的特殊情況有所幫助。我更新到NSubstitute的最新版本,我卸載/重新安裝,但仍然沒有任何東西。

再次,在此先感謝!

回答

0

這裏是結束了工作:

var context = Substitute.For<MyCoolApplicationsEntities>(); 

var applications = new List<Application> 
{ 
    new Application {AppID = 1, ApplicationName = "MyCoolApplication"} 
}; 

var mockApplications = Substitute.For<DbSet<Application>, IQueryable<Application>>(); 
((IQueryable<Application>)mockApplications).Provider.Returns(applications.AsQueryable().Provider); 
((IQueryable<Application>)mockApplications).Expression.Returns(applications.AsQueryable().Expression); 
((IQueryable<Application>)mockApplications).ElementType.Returns(applications.AsQueryable().ElementType); 
((IQueryable<Application>)mockApplications).GetEnumerator().Returns(applications.AsQueryable().GetEnumerator()); 

mockApplications.When(q => q.Add(Arg.Any<Application>())) 
    .Do(q => applications.Add(q.Arg<Application>())); 

mockApplications.When(q => q.Remove(Arg.Any<Application>())) 
    .Do(q => applications.Remove(q.Arg<Application>())); 

context.Applications = mockApplications; 
7

NSubstitute不能模擬非虛擬成員。 (有quite a few caveats to substituting for classes。)

MyCoolApplicationsEntities.Applications將需要虛擬爲.Returns()工作。

+0

大衛,感謝尋找這個。今天早上我能夠在同事的幫助下工作。如果你願意,請看我的答案。再次感謝! – Timothy 2014-12-05 15:59:53

+0

@蒂莫西,很高興你把它分類!所以這個概念沒有通過IQueryable接口?這意味着'context.Applications.Returns(mockApplications)'現在應該可以正常工作? – 2014-12-08 02:02:46

+0

context.Applications.Returns(mockApplications)仍然拍攝同樣的錯誤。 context.Applications = mockApplications現在可以工作。 – Timothy 2014-12-08 14:38:34

相關問題