我正在编写一个我已经部署到appharbor的应用程序。我现在无法让我的项目构建,因为我扩展了我的测试。我相信问题是我使用db初始化程序用测试种子数据填充数据库。这些测试通过我的本地盒子,但是一旦我在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 harbour上再次成功运行?
答案 0 :(得分:1)
实际上,您尚未验证控制器与其依赖项(存储库)之间的交互。这是最重要的部分 - 控制器应该将您的Lead
对象传递给存储库。然后调用Save
(也考虑工作单元模式)。
另外,您应该单独测试控制器,只有这样您可以确定,控制器测试失败是控制器的问题,而不是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());
BTW我已将预期的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
}
BTW为什么你没有将Lead
对象传递给你的动作方法(通过POST消息)?
答案 1 :(得分: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);