我必须对ASP.NET MVC 4.0中一个非常大且未格式化的方法进行单元测试。
以下是行动守则方法: -
public ActionResult GetDetails(string ProdName, int ProdArea, int ProdAreaId= 0)
{
if (ProdAreaId == 0 && ProdArea == 1 && System.Web.HttpContext.Current.Session["ResponseProdAreaId"] != null)
{
ProdAreaId = (int)System.Web.HttpContext.Current.Session["ResponseProdAreaId"];
}
if (string.IsNullOrEmpty(ProdName))
{
if (System.Web.HttpContext.Current.Session["ProdName"] == null)
{
ProdName = Guid.NewGuid().ToString();
System.Web.HttpContext.Current.Session["ProdName"] = ProdName;
}
else
{
ProdName = System.Web.HttpContext.Current.Session["ProdName"].ToString();
}
}
else
{
ProdName = ProdName.Replace("___", " ");
}
List<StateDetail> stateList = ProductService.GetAllStates().Where(n => n.FKCountryID == (int)Countries.UnitedStates).ToList();
ProductAddressViewModel model = new ProductAddressViewModel
{
ProdArea = ProdArea,
FKProductID = CurrentProductId
};
model.States = stateList != null ? new SelectList(stateList, "StateID", "StateCode") : null;
if (System.Web.HttpContext.Current.Session[“ProdAddresses”] != null && ProdAreaId == 0 && ProdArea == 1)
{
List<ProductAddressDto> lstprodaddresses = (List<ProductAddressDto>)System.Web.HttpContext.Current.Session[“ProdAddresses”];
if (lstprodaddresses.Count > 0)
{
AddressDto addrDto = lstprodaddresses.First().Address;
//save address in DB
model.Address1 = addrDto.Address1;
model.Address2 = addrDto.Address2;
model.ProdArea = 1;
model.City = addrDto.City;
model.IsDefault = true;
model.ProdName = model.ProdName;
model.SelectedAddressTypeID = (int)AddressType.Street;
model.ZIPCode = addrDto.ZIPCode;
model.SelectedStateId = addrDto.FKStateID;
model.AddressTypes = GetAddressTypes();
}
}
else if (model.FKProductID > 0)
{
ToolDto tool = ToolService.GetToolDetails(model.FKProductID);
if (ProdAreaId > 0)
{
model.AddressTypes = GetAddressTypes();
ProductAddressDto prodaddr = tool.ToolAddresses.First(n => n.Tool_AddressID == ProdAreaId);
model.Address1 = prodaddr.Address.Address1;
model.Address2 = prodaddr.Address.Address2;
model.City = prodaddr.Address.City;
model.SelectedStateId = prodaddr.Address.FKStateID;
model.ZIPCode = prodaddr.Address.ZIPCode;
model.SelectedAddressTypeID = prodaddr.Address.FKAddressTypeID;
model.IsDefault = prodaddr.IsDefault;
model.FKAddressID = prodaddr.FKAddressID;
model.Tool_AddressID = prodaddr.Tool_AddressID;
model.FKProductID = prodaddr.FKProductID;
model.AddressTypes = GetAddressTypes();
}
else
{
//address types
List<int> excludeAddrTypes = new List<int>();
foreach (ProductAddressDto prodadrdto in tool.ToolAddresses)
{
if (prodadrdto.Tool_AddressID != ProdAreaId)
{
excludeAddrTypes.Add(prodadrdto.Address.FKAddressTypeID);
}
}
if (System.Web.HttpContext.Current.Session[“ProdAddresses”] != null)
{
excludeAddrTypes.Add((int)AddressType.Street);
}
var addrtypes = from AddressType e in Enum.GetValues(typeof(AddressType))
where !excludeAddrTypes.Contains((int)e)
select new { Id = (int)e, Name = e.ToString() };
model.AddressTypes = addrtypes.Select(x => new SelectListItem
{
Value = x.Id.ToString(),
Text = x.Name
});
if (tool.ToolAddresses.Count == 0)
{
model.IsDefault = (ProdArea == 1);
}
}
}
else
{
//filter out address types if responsed tool is there
if (System.Web.HttpContext.Current.Session[“ProdAddresses”] != null)
{
List<int> excludeAddrTypes = new List<int>();
excludeAddrTypes.Add((int)AddressType.Street);
var addrtypes = from AddressType e in Enum.GetValues(typeof(AddressType))
where !excludeAddrTypes.Contains((int)e)
select new { Id = (int)e, Name = e.ToString() };
model.AddressTypes = addrtypes.Select(x => new SelectListItem
{
Value = x.Id.ToString(),
Text = x.Name
});
}
else
{
model.AddressTypes = GetAddressTypes();
}
model.IsDefault = (ProdArea == 1);
}
model.ProdName = ProdName;
return PartialView("_AddUpdateAddress", model);
}
可能方法格式不正确。但我必须进行单元测试。我已经用不同的方式做了。但我不确定它的正确性。 我想知道我们应该如何对这样一个大而无格式的方法进行单元测试。
任何人都可以帮我解决这个问题吗?
以下是我的单元测试方法的代码: -
[TestMethod]
public void GetDetailsTest_NotEmpty()
{
var ProdName = random.ToString();
var ProdArea = random.Next();
var ProdAreaId = 0;
var _toolServiceMock = new Mock<IToolService>();
var _lookupServiceMock = new Mock<ILookupService>();
var stateList = new List<StateDto> {
new StateDto() { StateID = random.Next(), StateCode = Guid.NewGuid().ToString(), Description = random.ToString(), FKCountryID = 1 },
new StateDto() { StateID = random.Next(), StateCode = Guid.NewGuid().ToString(), Description = random.ToString(), FKCountryID = random.Next() },
};
_lookupServiceMock.Setup(s => s.GetAllStates()).Returns(stateList); // .Returns(stateList);
//Arrange
CustomerDto cust = _toolService.LookupCustomers("", "").FirstOrDefault();
if (cust != null)
{
ToolDto tool = _toolService.GetToolDetails(cust.Tool.toolId);
if (tool.ToolAddresses.Count > 0 && tool.ToolAddresses.First().Address != null)
{
HttpContext.Current.Session["FKToolID"] = cust.FKToolID;
var controller = new ToolController(_toolServiceMock.Object);
PartialViewResult result = controller.SelectAddress(cust.Tool.Name, 1, tool.ToolAddresses.First().Tool_AddressID) as PartialViewResult;
var viewmodel = (ToolAddressViewModel)((ViewResultBase)(result)).Model;
if (viewmodel != null)
{
//Act
Assert.AreEqual(tool.ToolAddresses.First().Address.Address1, viewmodel.Address1);
Assert.AreEqual("_AddUpdateAddress", result.ViewName);
Assert.IsInstanceOfType(viewmodel, typeof(ToolAddressViewModel));
}
//Act
_lookupServiceMock.VerifyAll();
}
}
}
答案 0 :(得分:0)
首先,你的方法太复杂太长了。 使您的行动简短,并且有责任遵守SOLID原则(http://en.wikipedia.org/wiki/SOLID_(object-oriented_design))。 它将使您的方法更容易测试。
为了帮助您解决问题,您可以使用代码快速执行操作:
这是在不破坏现有应用程序的情况下测试逻辑的最简单方法。 不方便的是,你的逻辑是内部方法,让整个组件都能够使用它。