8

私は、 ASP.NET MVC Beta 1に関する Scott Guthrie の優れた投稿に取り組んできました。その中で彼は、UpdateModel メソッドに加えられた改善と、それによって単体テストがどのように改善されるかを示しています。同様のプロジェクトを再作成しましたが、UpdateModel への呼び出しを含む UnitTest を実行するたびに、controllerContext パラメーターを指定する ArgumentNullException を受け取ります。

私のモデルから始めて、関連するビットは次のとおりです。

public class Country {
  public Int32 ID { get; set; }
  public String Name { get; set; }
  public String Iso3166 { get; set; }
}

コントローラーのアクション:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Int32 id, FormCollection form)
{
  using ( ModelBindingDataContext db = new ModelBindingDataContext() ) {
    Country country = db.Countries.Where(c => c.CountryID == id).SingleOrDefault();

    try {
      UpdateModel(country, form);

      db.SubmitChanges();

      return RedirectToAction("Index");
    }
    catch {
      return View(country);
    }
  }
}

そして最後に、失敗している私の単体テスト:

[TestMethod]
public void Edit()
{
  CountryController controller = new CountryController();
  FormCollection form = new FormCollection();
  form.Add("Name", "Canada");
  form.Add("Iso3166", "CA");

  var result = controller.Edit(2 /*Canada*/, form) as RedirectToRouteResult;

  Assert.IsNotNull(result, "Expected to be redirected on successful POST.");
  Assert.AreEqual("Show", result.RouteName, "Expected to redirect to the View action.");
}

ArgumentNullExceptionUpdateModelへの呼び出しによって、 「値を null にすることはできません。パラメータ名: controllerContext」というメッセージがスローされます。テストの実行中に存在しないUpdateModelが必要な場所があると想定しています。System.Web.Mvc.ControllerContext

また、どこかで何か間違ったことをしていて、正しい方向に向ける必要があるだけだと思います。

助けてください!

4

3 に答える 3

5

UpdateModel が使用する TryUpdateModel は、単体テストから呼び出されたときに null である ControllerContext を参照するため、実行できないと思います。RhinoMocks を使用して、コントローラーに必要なさまざまなコンポーネントをモックまたはスタブします。

var routeData = new RouteData();
var httpContext = MockRepository.GenerateStub<HttpContextBase>();
FormCollection formParameters = new FormCollection();

EventController controller = new EventController();
ControllerContext controllerContext = 
    MockRepository.GenerateStub<ControllerContext>( httpContext,
                                                    routeData,
                                                    controller );
controller.ControllerContext = controllerContext;

ViewResult result = controller.Create( formParameters ) as ViewResult;

Assert.AreEqual( "Event", result.Values["controller"] );
Assert.AreEqual( "Show", result.Values["action"] );
Assert.AreEqual( 0, result.Values["id"] );

www.codeplex.com/aspnet の Controller.cs ソースからの関連ビットを次に示します。

protected internal bool TryUpdateModel<TModel>( ... ) where TModel : class
{

     ....

    ModelBindingContext bindingContext =
           new ModelBindingContext( ControllerContext,
                                    valueProvider,
                                    typeof(TModel),
                                    prefix,
                                    () => model,
                                    ModelState,
                                    propertyFilter );

     ...
}
于 2008-12-01T20:27:52.837 に答える
3

私はこれと同じ問題を抱えていました。tvanfossonのソリューションを読んだ後、モックフレームワークを含まない単純なソリューションを試しました。

次のように、デフォルトのControllerContextをコントローラーに追加します。

CountryController controller = new CountryController();
controller.ControllerContext = new ControllerContext();

これにより、単体テスト中のエラーが問題なく削除されました。これが他の誰かを助けるかもしれないことを願っています。

于 2010-12-03T20:47:54.900 に答える
0

または、フォーム データ プロキシを作成することもできます。

public class CountryEdit {
  public String Name { get; set; }
  public String Iso3166 { get; set; }
}
  • プラス。簡単に単体テストを作成
  • プラス。投稿から更新されるフィールドのホワイト リストを定義する
  • プラス。簡単に検証ルールを設定し、簡単にテストできます。
  • マイナス。日付をプロキシからモデルに移動する必要があります

したがって、Controller.Action は次のようになります。

public ActionResult Edit(Int32 id, CountryEdit input)
{
  var Country = input.ToDb();
  // Continue your code
}
于 2010-03-31T10:28:59.393 に答える