当我需要对调用其他类的多个公共方法的方法进行单元测试时,我会感到非常困惑。以下是一个例子:
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using SkillKindle.BLL;
using SkillKindle.BLL.ClassDetails;
using SkillKindle.BLL.SkClasses;
using SkillKindle.Domain.Models.SkClasses;
using SkillKindle.Infrastructure;
using SkillKindle.Web.Core.Infrastructure.ErrorHandling;
using SkillKindleWeb.Mappers;
using SkillKindleWeb.ViewModels.ClassDetails;
namespace SkillKindleWeb.Controllers
{
[CustomHandleError(ExceptionType = typeof (BusinessValidationException))]
public class ClassDetailsController : BaseController
{
private readonly ILogger _logger;
private readonly IMapperService _mapperService;
private readonly IAccessorFactory _accessorFactory;
private const int RegistrationId = 34;
private IClassDetailsAccessor ClassDetailsAccessor
{
get { return _accessorFactory.CreateClassDetailsAccessor(); }
}
private ISkClassAccessor SkClassAccessor
{
get { return _accessorFactory.CreateSkClassAccessor(); }
}
private IClassCreativeAccessor ClassCreativeAccessor
{
get { return _accessorFactory.CreateClassCreativeAccessor(); }
}
public ClassDetailsController(ILogger logger, IMapperService mapperService,
IAccessorFactory accessorFactory)
{
_logger = logger;
_mapperService = mapperService;
_accessorFactory = accessorFactory;
}
public ViewResult Index(int classCreativeId)
{
var classCreative = ClassCreativeAccessor.GetClassCreative(classCreativeId);
if (classCreative == null)
{
throw new HttpException(404, "The url is not valid");
}
var batches = ClassCreativeAccessor.GetFutureBatches(classCreativeId);
IList<ClassTicket> tickets = new List<ClassTicket>();
IList<Venue> venues = new List<Venue>();
if (batches.Count > 0)
{
tickets =
ClassCreativeAccessor.GetTickets(
batches.Select(batch => batch.ClassScheduleId).Distinct().ToArray());
venues = SkClassAccessor.GetVenues(batches.Select(batch => batch.VenueId).Distinct().ToArray());
}
var classDetailsViewModel = _mapperService.ClassCreativeToClassDetailsViewModel(classCreative);
var batchViewModels = _mapperService.BatchToClassDetailsBatchViewModel(batches).ToList();
var ticketViewModels = _mapperService.ClassTicketToClassDetailsTicketViewModel(tickets).ToList();
var venueViewModels = _mapperService.VenueToClassDetailsVenueViewModel(venues).ToList();
var indexViewModel = new IndexViewModel()
{
Batches = batchViewModels,
Tickets = ticketViewModels,
ClassDetails = classDetailsViewModel,
Venues = venueViewModels
};
return View(indexViewModel);
}
}
}
这里的Index方法依赖于mapperService、SkClassAccessor、ClassDetailsAccessor和ClassCreativeAccessor的公共方法。我已经单独对这些公共方法进行了单元测试。现在,当测试Index方法时,我需要检查indexViewModel的正确性。以下是我手头的几个选项。
选项1:模拟依赖类的公共方法以返回虚假对象,并检查IndexViewModel是否具有这些虚假对象。我不确定这是否是一个真正的测试。而且它并没有测试我是否将正确的参数传递给这些模拟的公共方法。
选项2:不要模拟依赖类的公共方法,而是伪造依赖类的依赖关系。例如,伪造票据列表ClassCreativeAccessor.GetTickets将操作。这种方法将验证我是否将正确的参数传递给依赖的公共方法。但这里我将再次测试公共方法。
我不确定哪种方法是正确的。感谢您的帮助。