![](/img/trans.png)
[英]Unity, Moq, and NUnit - Controller Constructor with Parameters Not Recognized in Tests
[英]Moq controller tests with repeated setup
我開始使用Moq框架並且非常喜歡它。 我正在編寫一些控制器測試,它們有幾個服務和接口來安排我的控制器進行測試。 我想更多地模塊化它,並認為這將是一項微不足道的任務,但事實證明它比我想象的要復雜一些。
這是一個簡單的單元測試,我必須展示一個例子:
[Test]
public void Get_SignIn_Should_Return_View()
{
#region //TODO: figure out how to extract this out to avoid duplicate code
// Arrange
var membershipService = new Mock<IMembershipService>();
var formsService = new Mock<IFormsAuthenticationService>();
var userService = new Mock<IUserService>();
var dictService = new Mock<IDictionaryService>();
var shoppingBasketService = new Mock<IShoppingBasketService>();
//Create the service provider mock and pass in the IRepositoryFactory so that it isn't instantiating real repositories
var repoFactory = new Mock<IRepositoryFactory>();
var serviceProvider = new Mock<ServiceProvider>( (IRepositoryFactory)repoFactory.Object );
var context = new Mock<HttpContextBase> { DefaultValue = DefaultValue.Mock };
var sessionVars = new Mock<SessionVars>();
AccountController controller = new AccountController( serviceProvider.Object, sessionVars.Object )
{
FormsService = formsService.Object,
MembershipService = membershipService.Object,
UserService = userService.Object,
DictionaryService = dictService.Object,
ShoppingService = shoppingBasketService.Object
};
controller.ControllerContext = new ControllerContext()
{
Controller = controller,
RequestContext = new RequestContext( context.Object, new RouteData() )
};
#endregion
// Act
ActionResult result = controller.SignIn();
// Assert
Assert.IsInstanceOf<ViewResult>( result );
}
我希望能夠做的是將#region
所有內容解壓縮到輔助方法或[Setup]方法中,但如果我這樣做,那么我就無法訪問每個模擬服務來設置期望。
有沒有我在這里缺少的東西,或者我是否真的必須在每個單元測試中復制並粘貼這一排編碼?
嘗試使用上下文來設置所有模擬,然后使用繼承上下文的測試工具 。 將測試放在這些燈具和violà中! 此代碼可能不適合您正在使用的框架。 如果它是NUnit那么它將是。 但理論是存在的。
public abstract class MembershipTestContext
{
var membershipService = new Mock<IMembershipService>();
var formsService = new Mock<IFormsAuthenticationService>();
var userService = new Mock<IUserService>();
var dictService = new Mock<IDictionaryService>();
var shoppingBasketService = new Mock<IShoppingBasketService>();
//Create the service provider mock and pass in the IRepositoryFactory so that it isn't instantiating real repositories
var repoFactory = new Mock<IRepositoryFactory>();
var serviceProvider = new Mock<ServiceProvider>( (IRepositoryFactory)repoFactory.Object );
var context = new Mock<HttpContextBase> { DefaultValue = DefaultValue.Mock };
var sessionVars = new Mock<SessionVars>();
[SetUp]
AccountController controller = new AccountController( serviceProvider.Object, sessionVars.Object )
{
FormsService = formsService.Object,
MembershipService = membershipService.Object,
UserService = userService.Object,
DictionaryService = dictService.Object,
ShoppingService = shoppingBasketService.Object
};
controller.ControllerContext = new ControllerContext()
{
Controller = controller,
RequestContext = new RequestContext( context.Object, new RouteData() )
};
}
[TestFixture]
public class when_getting_sign_in : MembershipContext
{
[Test]
public void Should_return_view()
{
// Act
ActionResult result = controller.SignIn();
// Assert
Assert.IsInstanceOf<ViewResult>(result);
}
[Test]
public void Should_do_another_test()
{
... another test etc
}
}
您可以做的一件事是使用Mock.Get
方法( http://api.moq.me/html/C6B12927.htm )來檢索給定對象實例的模擬。
另一種選擇是重構代碼並在測試類的實例變量中存儲對模擬對象的引用(如果測試類中的所有測試都需要它們)或者可能是簡單的數據結構(如果只需要一些測試)他們)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.