1

我正在编写一个已部署到 appharbor 的应用程序。我现在无法构建我的项目,因为我已经扩展了我的测试。我相信问题在于我正在使用数据库初始化程序来使用测试种子数据填充数据库。这些测试在我的本地机器上通过,但是一旦我在 appharbor 上部署测试失败。我怀疑我需要模拟数据,但我不知道该怎么做。例如,这是我对我的一种操作方法进行的控制器测试。

控制器

    // 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);

    }

有人可以解释一下我接下来需要做什么来改进这样的代码并让它在 app Harbor 上成功运行吗?

4

2 回答 2

1

实际上,您还没有验证控制器与其依赖项(存储库)之间的交互。这是最重要的部分 - 控制器应该将您的Lead对象传递给存储库。然后调用Save(也考虑到工作单元模式)。

此外,您应该单独测试控制器,只有这样您才能确定控制器测试失败是控制器的问题,而不是LeadRepositoryor的问题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),并存根每个方法。

像这样的东西(起订量):

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 回答