1

appharborにデプロイしているアプリを書いています。テストを拡張したため、プロジェクトをビルドするのに問題があります。問題は、データベースにテストシードデータを入力するためにdb初期化子を使用していることだと思います。これらのテストは私のローカルボックスで合格しますが、一度デプロイすると、appharborでテストが失敗します。データをモックする必要があると思いますが、その方法がわかりません。例として、アクションメソッドの1つに対して行ったコントローラーテストを次に示します。

コントローラ

    // GET: /Lead/Url
    // TODO: Add optional url parameters
    public ActionResult Url(string pfirstname, string plastname, string phone, int leadsource)
    {

        var lead = new Lead();
        //store 
        lead.parent_FirstName = pfirstname;
        lead.parent_LastName = plastname;
        lead.parent_Phone = phone;
        lead.LeadSourceID = leadsource;
        lead.AgentID = 1;

        if (ModelState.IsValid)
        {
            leadRepository.InsertLead(lead);
            leadRepository.Save();
            ViewBag.Message = "Success";
        }

        return View(lead);
    }

    //
    // POST: /Lead/URL       
    [HttpPost, ActionName("Url")]
    public ActionResult Url(Lead lead)
    {
        return View();
    }

単体テスト

[TestMethod]
    public void LeadUrl()
    {
        //ARRANGE
        ILeadRepository leadrepository = new LeadRepository(new LeadManagerContext());
        Database.SetInitializer<LeadManagerContext>(new LeadManagerInitializer());
        LeadController controller = new LeadController(leadrepository);

        //ACT
        ViewResult result = controller.Url("Brad", "woods","465-456-4965",1) as ViewResult;
        var lead = (Lead)result.ViewData.Model;

        //ASSERT
       Assert.AreEqual("Success" ,result.ViewBag.Message);
        /*check for valid data */
       Assert.AreEqual("Brad", lead.parent_FirstName);

    }

このようなコードを改善し、アプリハーバーで正常に実行できるようにするために、次に何をする必要があるかを誰かに説明してもらえますか?

4

2 に答える 2

1

実際には、コントローラーとその依存関係 (リポジトリ) の間の相互作用を確認していません。これが最も重要な部分です。コントローラーはLeadオブジェクトをリポジトリに渡す必要があります。そして呼び出しますSave(Unit Of Work パターンも考慮してください)。

また、コントローラーを分離してテストする必要があります。この方法でのみ、失敗したコントローラーのテストはコントローラーの問題であり、LeadRepositoryまたはではありませんLeadManagerInitializer

// Arrange
Lead expected = CreateBrad();    
var repository = new Mock<ILeadRepository>();
LeadController controller = new LeadController(repository.Object);    
// Act
ViewResult result = (ViewResult)controller.Url("Brad", "woods", "465-456", 1);
// Assert      
Lead actual = (Lead)result.ViewData.Model;
// All fields should be equal, not only name
Assert.That(actual, Is.EqualTo(expected));
Assert.AreEqual("Success", result.ViewBag.Message);
// You need to be sure, that expected lead object passed to repository
repository.Verify(r => r.InsertLead(expected));
repository.Verify(r => r.Save());

ところで、予想されるLead作成を別の方法に移動しました:

private Lead CreateBrad()
{
    Lead lead = new Lead();
    lead.parent_FirstName = "Brad";
    lead.parent_LastName = "woods";
    lead.parent_Phone = "465-456";
    lead.LeadSourceID = 1;
    lead.AgentID = 1;
    return lead;
}

また、インスタンス比較Equalsのためにメソッドをオーバーライドする必要があります。Lead

public class Lead
{
   // your current code here

   public override bool Equals(object obj)
   {
       Lead other = obj as Lead;
       if (other == null)
           return false;

       return other.parent_FirstName == parent_FirstName &&
              other.parent_LastName == parent_LastName &&
              // compare other properties here
              other.AgentID == AgentID;
   }

   // also override GetHashCode method
}

Leadところで、(POST メッセージを介して) アクション メソッドにオブジェクトを渡さないのはなぜですか?

于 2012-07-24T13:32:14.687 に答える
1

リポジトリをスタブする必要があります。これを行う最も簡単な方法は、モック フレームワーク (私はMoqを好む) を使用し、各メソッドをスタブ化することです。

このようなもの(Moqの場合):

var repository = new Mock<ILeadReporisory>();
repository.Setup(r => r.InsertLead(It.IsAny<Lead>()));
//raise, rinse, repeat

LeadController controller = new LeadController(repository.Object);
于 2012-07-24T13:33:02.270 に答える