问题
I have a method in code that returns an OrganisationModel.
public virtual OrganisationModel GetCurrentUserOrganisation()
{
var user = DBEntities.AspNetUsers.Find(_userId);
if (user.ActiveOrganisation != null)
{
var org = user.OrganisationUsers.Where(p => p.organisationId ==
user.ActiveOrganisation).Where(p => p.userId == _userId).FirstOrDefault();
if(org != null)
{
if (org.Organisation != null)
{
return org.Organisation.ToModel();
}
return null;
}
else
{
return null;
}
}
return null;
}
I want to write a unit test on a class that uses this method my test looks like this
public void Index()
{
HttpContext.Current = _TestContext;
var _GovernorLogic = new Mock<GovernorLogic>();
var testdata = new OrganisationModel { OrganisationId = 3, OrganisationName = "Test Org" };
var _OrganisationLogic = new Mock<OrganisationLogic>(new UserId { userId = "e58bf834-2c06-4cc0-ac00-231a5e1a9bbc" }) ;
_OrganisationLogic.Setup((OrganisationLogic p) => p.GetCurrentUserOrganisation()).Returns((OrganisationModel model) => testdata).Callback((OrganisationLogic a) => receivedorganisation = a.GetCurrentUserOrganisation());
GovernorsController controller = new GovernorsController(_OrganisationLogic.Object);
ViewResult result = controller.Index() as ViewResult;
Assert.IsNotNull(result);
}
When I run this I get an error telling me that
System.ArgumentException Invalid callback. Setup on method with 0 parameter(s) cannot invoke callback with different number of parameters (1). Source=Moq StackTrace: at Moq.MethodCallReturn
2.ValidateNumberOfCallbackParameters(MethodInfo callbackMethod) at Moq.MethodCallReturn
2.ValidateReturnDelegate(Delegate callback) at Moq.MethodCallReturn2.Returns[T](Func
2 valueExpression)
How do I test a method that accepts no input parameters but has a return type?
The Controller Action Method I am trying to test is shown below along with the Constructor for the Controller.
[Inject]
public GovernorsController(GovernorLogic GovernorLogic, OrganisationLogic logic) : base(logic)
{
_GovernorLogic = GovernorLogic;
}
public ActionResult Index()
{
var CurrentGovernors = _GovernorLogic.GetAllCurrentGovernors(Organisation.GetCurrentUserOrganisation().OrganisationId).ToList().Select(p => p.ToViewModel()).ToList();
var ArchivedGovernors = _GovernorLogic.GetAllArchivedGovernors(Organisation.GetCurrentUserOrganisation().OrganisationId).ToList().Select(p => p.ToViewModel()).ToList();
var Model = new GovernorsViewModel
{
CurrentGovernors = CurrentGovernors,
ArchivedGovernors = ArchivedGovernors,
};
return View(Model);
}
The base controller that is inherited by GovernorsController is shown below:
public class BaseController : Controller
{
private OrganisationLogic _organisationLogic;
private ApplicationSignInManager _signInManager;
private ApplicationUserManager _userManager;
private string _userId;
[Inject]
public BaseController(OrganisationLogic OrganisationLogic)
{
_userId = System.Web.HttpContext.Current.User.Identity.GetUserId();
_organisationLogic = new OrganisationLogic(new UserId {userId= System.Web.HttpContext.Current.User.Identity.GetUserId()});
}
protected OrganisationLogic Organisation
{
get
{
return _organisationLogic;
}
}
public BaseController(ApplicationUserManager userManager, ApplicationSignInManager signInManager)
{
UserManager = userManager;
SignInManager = signInManager;
}
public ApplicationSignInManager SignInManager
{
get
{
return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
}
set
{
_signInManager = value;
}
}
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
set
{
_userManager = value;
}
}
}
------ Minimal Complete Example -------
Base Controller
public class BaseController : Controller
{
private OrganisationLogic _organisationLogic;
private string _userId;
[Inject]
public BaseController(OrganisationLogic OrganisationLogic)
{
_userId = System.Web.HttpContext.Current.User.Identity.GetUserId();
_organisationLogic = new OrganisationLogic(new UserId {userId= System.Web.HttpContext.Current.User.Identity.GetUserId()});
}
[ChildActionOnly]
public ActionResult UserOrganisations()
{
if (User.Identity.IsAuthenticated)
{
var ViewModel = _OrganisationLogic.GetAll().ToList().Select(p=>p.ToViewModel());
return PartialView("_UserOrganisations", ViewModel);
}
return null;
}
}
///The child action in the base controller is use in the layout page to render organisation in a drop down list. It is this that is making use of _OrganisationLogic /////
@Html.Action("UserOrganisations", "Base",new {area = "" })
GovernorsController
public class GovernorsController : OrganisationBaseController
{
[Inject]
public GovernorsController(OrganisationLogic logic) : base(logic)
{
}
// GET: Organisation/Governors
public ActionResult Index()
{
var Model = new SomeModel();
return View(Model);
}
}
OrganisationLogic
public class OrganisationLogic : LogicRepository<OrganisationModel>
{
private string _userId;
public OrganisationLogic(UserId userId)
{
_userId = userId.userId;
}
public override List<OrganisationModel> GetAll()
{
var orgs = DBEntities.Organisations.Where(p=>p.IsDeleted!=true).ToList().Select(p=>p.ToModel()).ToList();
return orgs;
}
}
来源:https://stackoverflow.com/questions/49211389/how-do-you-mock-an-class-for-a-unit-test-that-has-a-return-type-but-no-input-par