MockBean always returns false - spring-test

This is the function in my controller that I wanna test
#PostMapping("/register")
public String postRegister(#ModelAttribute("regForm") #Valid RegistrationForm form,
BindingResult bind,
Model model) {
model.addAttribute("regForm", form);
if (!userService.register(form.getEmail(), form.getPassword(), form.getName())
.isPresent()) {
inputError(bind, "regForm", "password");
return "register";
}
return "redirect:/";
}
This is the test
#Test
public void postRegister() throws Exception {
when(userService.register("test", "test", "test")).
thenReturn(Optional.of(new UserDTO(1, "test", "test")));
mockMvc.perform(post("/register"))
.andExpect(status().isOk())
.andExpect(model().attribute("regForm", new RegistrationForm()))
.andExpect(view().name("register"));
}
The problem is that "isPresent" in the controller always works like "false" even with "thenReturn" object is presented and it always returns "register" view form when I wanna get "redirect:/"
How to solve it? Thanks

Related

Getting error UserSession.OnActionExecuting(ActionExecutingContext): no suitable method found to override in mvc 5?

I have created one demo in mvc 5 and now I need to create one custom filter in my demo. I have used mvc 5.
I need to check every time what method is execute like is a ajax call or action method call in mvc.
Here I have write like this code in my class.
public class UserSession
: System.Web.Http.Filters.ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var session = filterContext.HttpContext.Session;
if (ApplicationSession.IsSessionAlive)
return;
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
var ajaxRedirectTarget = new RouteValueDictionary { { "action", "FailAuthenticationAjax" }, { "controller", "Home" } };
filterContext.Result = new RedirectToRouteResult(ajaxRedirectTarget);
}
else
{
var redirectTarget = new RouteValueDictionary { { "action", "Login" }, { "controller", "Account" } };
filterContext.Result = new RedirectToRouteResult(redirectTarget);
}
}
}
but I got error like this UserSession.OnActionExecuting(ActionExecutingContext): no suitable method found to override
After I have put this class on my controller like this.
[UserSession]
public class DashboardController
{
}
any one know how to fixed this issue in mvc 5?

Getting captcha plugin to work with register action

I have the login portion working and the register page displays the captcha clearly, the .dll for RecaptchaMVC5 says that AccountController does not contain a definition for verifyReCAPTCHA but it works with the login portion:
Examples:
Login thats working:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
// Verify the recaptcha response.
ReCaptchaResponse response = await this.verifyReCAPTCHA(model, "key", true);
if (response.Success)
{
var user = await UserManager.FindAsync(model.UserName, model.Password);
if (user != null)
{
await SignInAsync(user, model.RememberMe);
return RedirectToLocal(returnUrl);
}
else
{
ModelState.AddModelError("", "Invalid username or password.");
}
}
else
{
ModelState.AddModelError("", "Invalid Captcha Code!");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
My Register Mockup that throws errors on verifyReCAPTCHA:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
//Verify the recaptcha response.
ReCaptchaResponse response = await this.verifyReCAPTCHA(model, "key", true);
if (response.Success)
{
var user = new ApplicationUser() { UserName = model.UserName };
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await SignInAsync(user, isPersistent: false);
return RedirectToAction("Index", "Home");
}
else
{
AddErrors(result);
}
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
the error I get
Error 1 'ReCaptchaMVC5Test.Controllers.AccountController' does not contain a definition for 'verifyReCAPTCHA'
Inside Models folder > AccountViewModels.cs There is
public class LoginViewModel : ReCaptchaViewModel
and
public class RegisterViewModel : <Place 'RecaptchaViewModel' Here>
That's how you assign the Captcha's view model to other models
assuming both these methods are on the AccountController, what is the method signature for verifyReCAPTCHA as the methods both send different models (LoginViewModel and RegisterViewModel) do both inherit from the correct base?
From what I can tell by the source, there's an extension method you're unable to access. Looks like you need to add using ReCaptcha.Mvc5; to the top of your Controller's source file to gain access.
verifyReCAPTCHA(this Controller, ReCaptchaViewModel, String, Boolean)
Also, make sure your model inherits from ReCaptcha.Mvc5.Model.ReCaptchaViewModel (as demonstrated in their documentation), that way you satisfy the method signature.

web api 2 - Passing data from action filter to action as an argument

In order to avoid getting the user data on every action I've create an custom action filter that gets the user by its ID and then passes to the action.
public class UserDataAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
...
// getting the user and storing it in the request properties
object user = userBLL.GetUserById(userId);
actionContext.Request.Properties.Add("User", user);
}
}
And the I can get the user object in the action method like this:
[Authorize]
[UserData]
[HttpGet]
[Route("dosomething")]
public IHttpActionResult DoSomething()
{
// retrieve the user
object user;
Request.Properties.TryGetValue("User", out user);
User u = (User)user;
return Ok();
}
However, in MVC it's possible to use ActionParameters in the filter to store something that will be used by the action method, like so:
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
...
// Create object parameter.
filterContext.ActionParameters["User"] = userBLL.GetUserById(userId);
}
And then use the User object as if it were part of the original request:
[AddActionParameter]
public ActionResult Index(User user)
{
// Here I can access the user setted on the filter
...
return View();
}
So, my question is: There is a way in Web API 2 to pass the User object from the action filter to the action as an argument, just like in MVC?
With ASP.NET Web API, you can create a parameter binding to receive an object, User in your case. You don't have to create a filter for this. So, you will create a binding like this.
public class UserParameterBinding : HttpParameterBinding
{
public UserParameterBinding(HttpParameterDescriptor descriptor) :
base(descriptor) { }
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider,
HttpActionContext context,
CancellationToken cancellationToken)
{
SetValue(context, new User() { // set properties here });
return Task.FromResult<object>(null);
}
}
Then, to use the binding, you will configure it, like this.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// snip
config.ParameterBindingRules.Insert(0, d =>
d.ParameterType == typeof(User) ? new UserParameterBinding(d) : null);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
With that, wherever you have User as action method parameter, it will automatically bind the instance you are creating inside UserParameterBinding to that parameter.

Specific TableController name not working

I have an extremely odd error and wondered if anyone knew the reason for this.
When I create a new DataObject and TableController called Content and ContentController respectively, it doesn't register the tablecontroller and the help documentation it automatically generates has lost its styling.
I can't connect to the controller at all but all other controllers work as expected.
If I just rename it to DataController and that's just the name of the controller, not the dataobject everything works perfectly.
Is ContentController a reserved word of some kind or is this just specifically happening on my machine?
public class DataController : TableController<Content>
{
protected override void Initialize(HttpControllerContext controllerContext)
{
base.Initialize(controllerContext);
MobileContext context = new MobileContext();
DomainManager = new EntityDomainManager<Content>(context, Request, Services);
}
// GET tables/Content
public IQueryable<Content> GetAllContent()
{
return Query();
}
// GET tables/Content/48D68C86-6EA6-4C25-AA33-223FC9A27959
public SingleResult<Content> GetContent(string id)
{
return Lookup(id);
}
// PATCH tables/Content/48D68C86-6EA6-4C25-AA33-223FC9A27959
public Task<Content> PatchContent(string id, Delta<Content> patch)
{
return UpdateAsync(id, patch);
}
// POST tables/Content/48D68C86-6EA6-4C25-AA33-223FC9A27959
public async Task<IHttpActionResult> PostContent(Content item)
{
Content current = await InsertAsync(item);
return CreatedAtRoute("Tables", new { id = current.Id }, current);
}
// DELETE tables/Content/48D68C86-6EA6-4C25-AA33-223FC9A27959
public Task DeleteContent(string id)
{
return DeleteAsync(id);
}
}
An MVC project will create an application directory called Content. This will override your route mapping to the ContentController.
You can get around this if desired through changing RouteMaps and other trickery although probably the simpliest answer is to change the name of the controller...

How to attach an existing View to a controller action?

How can I attach an existing View to an Action?
I mean, I've already attached this very View to an Action, but what I want is to attach to a second Action.
Example:
I've an Action named Index and a View, same name, attached to it, right click, add view..., but now, how to attach to a second one? Suppose an Action called Index2, how to achieve this?
Here's the code:
//this Action has Index View attached
public ActionResult Index(int? EntryId)
{
Entry entry = Entry.GetNext(EntryId);
return View(entry);
}
//I want this view Attached to the Index view...
[HttpPost]
public ActionResult Rewind(Entry entry)//...so the model will not be null
{
//Code here
return View(entry);
}
I googled it and cant find an proper answer...
It's possible?
you cannot "attach" actions to views but you can define what view you want be returned by an action method by using Controller.View Method
public ActionResult MyView() {
return View(); //this will return MyView.cshtml
}
public ActionResult TestJsonContent() {
return View("anotherView");
}
http://msdn.microsoft.com/en-us/library/dd460331%28v=vs.98%29.aspx
Does this help? You can use the overload of View to specify a different view:
public class TestController : Controller
{
//
// GET: /Test/
public ActionResult Index()
{
ViewBag.Message = "Hello I'm Mr. Index";
return View();
}
//
// GET: /Test/Index2
public ActionResult Index2()
{
ViewBag.Message = "Hello I'm not Mr. Index, but I get that a lot";
return View("Index");
}
}
Here is the View (Index.cshtml):
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>#ViewBag.Message</p>

Resources