2015-01-13 39 views
2

我試圖單元測試我的控制器,它包含ModelState.IsValid的檢查,但由於某種原因,無論我做什麼,我總是以無效的異常結束,無論我嘗試訪問ModelState (在單元測試和控制器功能中)。ModelState null當通過單元測試實例化控制器

無處不在我只是使用ModelState.Clear()/。AddModelError(),它似乎爲他們工作。有人說他們在mvc版本不同時會得到一個例外,但我已經檢查過並且他們是一樣的。

我可以錯過什麼?

赫雷什單元測試代碼:

private Mock<IRegistrationService> registrationService; 
    private RegistrationController registrationCtrl; 

    public RegisteringANewUser() 
    { 
     registrationService = new Mock<IRegistrationService>(); 
     registrationCtrl = new RegistrationController(registrationService.Object); 
     registrationCtrl.ModelState.Clear(); <- throws exception 
    } 

    [Fact] 
    public void ShouldRegisterUser_WhenInputIsCorrect() 
    { 

     var registration = RegistrationHelper.CreateRegistrationVM("username", "password", "[email protected]"); 

     registrationCtrl.Post(registration); 

     registrationService.Verify(s => s.Register(registration), Times.Once); 
    } 
    [Fact] 
    public void ShouldReturnBadRequest_WhenInputIsInvalid() 
    { 
     var registration = RegistrationHelper.CreateRegistrationVM("", "", ""); 
     registrationCtrl.ModelState.AddModelError("Error", "Error"); <- throws exception 
     var result = registrationCtrl.Post(registration); 

     Assert.Equal((int)HttpStatusCode.BadRequest, result.StatusCode); 
    } 

被測控制器功能:

public HttpStatusCodeResult Post(RegistrationVM registration) 
    { 
     if (!ModelState.IsValid) <- throws exception 
     { 
      return new HttpStatusCodeResult((int)HttpStatusCode.BadRequest); 
     } 

     _registrationService.Register(registration); 
     return new HttpStatusCodeResult((int)HttpStatusCode.OK); 
    } 

project.json用於單元測試庫:

{ 
"version": "1.0.0-*", 
"dependencies": { 
    "Web": "1.0.0-*", 
    "Moq": "4.2.1409.1722", 
    "Xunit.KRunner": "1.0.0-rc1-10618", 
    "Microsoft.AspNet.Mvc": "6.0.0-beta1" 
}, 

"frameworks": { 
    "aspnet50": { 
     "dependencies": { 
     } 
    } 

}, 
"commands": { 
    "test": "Xunit.KRunner" 
} 
} 

而對於網站項目:

{ 
/* Click to learn more about project.json http://go.microsoft.com/fwlink/?LinkID=517074 */ 
"webroot": "wwwroot", 
"version": "1.0.0-*", 
"dependencies": { 
    "Microsoft.AspNet.Mvc": "6.0.0-beta1", 
    //"Microsoft.AspNet.Mvc.WebApiCompatShim": "6.0.0-beta1", 
    "Microsoft.AspNet.Diagnostics": "1.0.0-beta1", 
    "Microsoft.AspNet.Security.Cookies": "1.0.0-beta1", 
    "Microsoft.AspNet.Server.IIS": "1.0.0-beta1", 
    "Microsoft.AspNet.Server.WebListener": "1.0.0-beta1", 
    "Microsoft.AspNet.StaticFiles": "1.0.0-beta1", 
    "Microsoft.Framework.ConfigurationModel.Json": "1.0.0-beta1", 
    "Microsoft.Framework.CodeGenerators.Mvc": "1.0.0-beta1", 
    "Microsoft.Framework.Logging": "1.0.0-beta1", 
    "Microsoft.Framework.Logging.Console": "1.0.0-beta1", 
    "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-beta1", 
    "mongocsharpdriver": "1.10.0.0-rc1" 
}, 
"commands": { 
    /* Change the port number when you are self hosting this application */ 
    "web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5000", 
    "gen": "Microsoft.Framework.CodeGeneration" 
}, 
"frameworks": { 
    "aspnet50": { }, 
    "aspnetcore50": { } <- tried to remove this as I dont have it in my unit test lib without success 
}, 
"exclude": [ 
    "wwwroot", 
    "node_modules", 
    "bower_components" 
], 
"packExclude": [ 
    "node_modules", 
    "bower_components", 
    "**.kproj", 
    "**.user", 
    "**.vspscc" 
], 
"scripts": { 
    "postrestore": [ "npm install" ], 
    "prepare": [ "grunt bower:install" ] 
} 
} 
+1

在你的操作方法,你真的是說如果執行你的壞請求邏輯模型狀態_is_有效嗎?或者,你的代碼應該是'if(!ModelState.IsValid)'強調'!'嗎? (也許這是故意的,但乍一看對我來說很奇怪。) – EF0

+0

哎呀!好,我正在爲此寫一個測試! – user1842278

+0

對這個問題有點困惑。你是說當你運行上面顯示的特定測試,並且測試執行了你的動作方法時,你的控制器中的if(ModelState.IsValid)行會拋出一個異常嗎?你是說,如果你在單元測試之外執行這個動作方法,也會發生這種情況(例如觸發UI)?你提到使用'.AddModelError()'來測試你的測試;但是我沒有在你的問題中看到特別的測試。 – EF0

回答

1

這確實是一個差距(直到beta3)。被這個Issue

跟蹤在Beta3中釋放(或者你可以得到在開發建立在一天左右),我們將初始化一個單元測試只ViewDataDictionary讓你的單元測試會得到一個空ModelState

這裏是一個從Controller.cs

[Activate] 
    public ViewDataDictionary ViewData 
    { 
     get 
     { 
      if (_viewData == null) 
      { 
       // This should run only for the controller unit test scenarios 
       _viewData = 
        new ViewDataDictionary(new EmptyModelMetadataProvider(), 
              ActionContext?.ModelState ?? new ModelStateDictionary()); 
      } 

      return _viewData; 
     } 
     set 
     { 
      if (value == null) 
      { 
       throw 
        new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(ViewData)); 
      } 

      _viewData = value; 
     } 
    } 

新代碼段(不改變代碼)

public ModelStateDictionary ModelState 
    { 
     get 
     { 
      return ViewData?.ModelState; 
     } 
    } 
+0

PR的鏈接不見了 –

+0

Thanks @MaurizioIndenmark。代碼很明顯。我將刪除鏈接 –