簡體   English   中英

Moq控制器測試重復設置

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM