Play framework Testing controller - spring

I am trying to test a controller using callAction
in ApplicationTest.java's testAction() method:
Result result =
callAction(controllers.routes.ref.Application.action(463), request);
testAction(int) refers to some of the fields(mySpringService) in Application controller. How and where these fields to be instantiated? Can I have setup() in AplicationTest.java??
public class Application extends Controller {
#Autowired privateMySpringService mySpringService;
public Result action(int waterQualityId){
mySpringService.doSomeMath(); return ok(); }
}
Any help is appreciated.

Related

Call two Action Methods and Combine the responses to produce new response in .NET Web API

I have two versions of an API.
The second version of API will be having only one action method instead of two action methods in first version of API.
Second version of API action method will basically combine responses of first version of API's both action methods and return combined response to client.
Example code as follows:
[ApiController]
[Route("[controller]")]
public class NumbersV1Controller : ControllerBase
{
private readonly ILogger<NumbersV1Controller> _logger;
public NumbersV1Controller(ILogger<NumbersV1Controller> logger)
{
_logger = logger;
}
[HttpGet]
public int Get()
{
return 1;
}
[HttpPost]
public int Post()
{
return 2;
}
}
[ApiController]
[Route("[controller]")]
public class NumbersV2Controller : ControllerBase
{
private readonly ILogger<NumbersV2Controller> _logger;
public NumbersV2Controller(ILogger<NumbersV2Controller> logger)
{
_logger = logger;
}
[HttpPost]
public IEnumerable<int> Get()
{
// Method 1: Make a direct HTTP request.
// int response1 = HTTPClientHelper.GetRequest("Get", "NumbersV1");
// int response2 = HTTPClientHelper.PostRequest("Post", "NumbersV1");
// Method 2: Use instances and set controller context.
NumbersV1Controller numbersV1Controller = new NumbersV1Controller(null);
numbersV1Controller.ControllerContext = this.ControllerContext;
int response1 = numbersV1Controller.Get();
int response2 = numbersV1Controller.Post();
// Method 3: Use RedirectToAction method.
// RedirectToActionResult response1 = RedirectToAction("Get", "NumbersV1");
// RedirectToActionResult response2 = RedirectToAction("Post", "NumbersV1");
return new List<int>() { response1, response2 };
}
}
Method 1: Make a direct HTTP request.
It works perfectly but it is having additional boilerplate code and also it like making a new network call.
Method 2: Use instances and set controller context.
Not sure if this will work perfectly like can I access the Request object in version 1 controller and not sure how to initialize the version 2 controller will multiple injected objects
Method 3: Use RedirectToAction method.
I was assuming RedirectToAction will work but I don't see the result of the Action method in response object RedirectToActionResult.
What are the best options available for doing this in .NET Web API or is there any other way of doing this elegently?
Avoid using method 2 / method 3. Why? It violates so many patterns and performance will be an issue.
Method 1 is average if you really want to do it that way but will cost a network call though.
Method 4:
You can call directly inline business logic code from your V2 controller. If you already separated your business logic code to an individual service then you need to call it from your controller.
I have introduced a new class to do all the logical operations. You might have a similar one / many service classes for handling business requirements.
Let me give you an example:
public class Number1Controller : BaseController {
// You can use DI container to resolve this. I am using this as an example.
private readonly Service _service = new();
[HttpGet("{id}")]
public int GetById(int id) => _service.GetById(id);
[HttpGet("{name}")]
public string GetByName(string name) => _service.GetByName(name);
}
public class Number2Controller : BaseController {
// You can use DI container to resolve this. I am using this as an example.
private readonly Service _service = new();
[HttpGet("{id}")]
public int GetById(int id) => _service.GetById(id);
[HttpGet("{name}")]
public string GetByName(string name) => _service.GetByName(name);
}
// Business Logic Service
public class Service {
public int GetById(int id) => 1;
public string GetByName(string name) => "Stack Over Flow";
}

Not able to mock Laravel Model method

I am currently writing a test to test a model method.
My model Store has this method:
public function hourTemplate() {
return $this->belongsTo(HourTemplate::class);
}
I have a test as well with this code in setUp method:
public function setUp() : void
{
parent::setUp();
$this->storeMock = Mockery::mock(StoreModel::class)->makePartial();
app()->instance(StoreModel::class, $this->storeMock);
}
And test method is like this:
public function test_getStoreHoursArray_when_hour_isNull() {
$this->storeMock->shouldReceive('hourTemplate')->andReturn(new HourTemplate());
dump((new StoreModel())->hourTemplate);
}
But the returned value is null.
You should retrieve the mocked instance from the container
$mockedModel = app()->make(StoreModel::class);

Laravel dependency injection into custom non-controller class fails in PHPUnit

all.
For a Laravel project I'm working on, I've started to use Dependency Injection in order to mock classes in my tests. However, I've found that if I try to inject into a custom class with no explicit parent, two things are true:
The dependency injection works correctly when running the application
The injection fails when running tests in PHPUnit
Here is some sample code similar to what I'm using:
DemoController
// The controller we're testing
class DemoController extends Controller
{
// The injection and constructor
private $helpLayer1;
public function __construct(HelpLayer1 $helpLayer1)
{
$this->helpLayer1 = $helpLayer1;
}
...
// The test function I call
public function testDeps()
{
$this->helpLayer1->testLayer1();
}
}
HelperLayer1
// Our first helper class
class HelperLayer1
{
private $helpLayer2;
public function __construct(HelpLayer2 $helpLayer2)
{
$this->helpLayer2 = $helpLayer2;
}
...
// The testing function
public function testLayer1()
{
// When called via route, this dumps the actual object
// When called via test, this returns null
dd($this->helperLayer2);
}
}
Helper1ServiceProvider
class Helper1ServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind('HelperLayer1', function()
{
return new HelperLayer1(App::make('HelperLayer2'));
});
}
[OR]
public function register()
{
$this->app->bind('HelperLayer1', 'HelperLayer1');
}
}
Helper2ServiceProvider
class Helper2ServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind('HelperLayer2', 'HelperLayer2');
}
}
I'm relatively new to using DI, so I'm not entirely sure that this set-up is correct, but I'm at a loss.
Any help would be greatly appreciated! Thank you!

How to access Identity UserManager in Web API Controller to Send an Email

I am using Identity v2 and need to send an Email from Web Api Controller using the UserManager.SendAsync method which is OWIN Middleware component. But I don't know how do I access the UserManager itself in Web Api Controller Method. I am trying a similar approach like a Regular MVC controller but usermanager always null. Any suggestion please?
public class MyApiController: ApiController
{
public MyApiController()
{
}
public MyApiController(ApplicationUserManager userManager)
{
UserManager = userManager;
}
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
public void SendEmail()
{
_userManager.SendAsync(...);
}
}
The constuctor that takes a ApplicationUserManager will never be called with your current solution. Change your empty constructor to call your other constructor.
public class MyApiController: ApiController
{
public MyApiController()
: this(new ApplicationUserManager())
{
}
THE REST OF YOUR IMPLEMENTATION GOES HERE
}
Check whether you have correctly configured UserManager from Startup class
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.DataProtection;
using Owin;
namespace Identity_PasswordPolicy
{
public partial class Startup
{
// For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder app)
{
///...
// Configure the UserManager
app.UseUserManagerFactory(new IdentityFactoryOptions<ApplicationUserManager>()
{
DataProtectionProvider = app.GetDataProtectionProvider(),
Provider = new IdentityFactoryProvider<ApplicationUserManager>()
{
OnCreate = ApplicationUserManager.Create
}
});
/// ...
}
}
}
Like here in Startup.Auth class from asp.net identity samples
https://aspnet.codeplex.com/SourceControl/latest#Samples/Identity/Identity-PasswordPolicy/Identity-PasswordPolicy/App_Start/Startup.Auth.cs
Startup is partial class and method ConfigureAuth by link is called from https://aspnet.codeplex.com/SourceControl/latest#Samples/Identity/Identity-PasswordPolicy/Identity-PasswordPolicy/Startup.cs
In sample it is called from owin startup method, but depending from hosing it could be called from global.asax.cs

Attribute routing and inheritance

I am playing around with the idea of having a base controller that uses a generic repository to provide the basic CRUD methods for my API controllers so that I don't have to duplicate the same basic code in each new controller. But am running into problems with the routing attribute being recognized when it's in the base controller. To show exactly what the problem I'm having I've created a really simple WebAPI controller.
When I have a Get method in the main Controller and it inherits from the ApiController directly I don't have any problems and this works as expected.
[RoutePrefix("admin/test")]
public class TestController : ApiController
{
[Route("{id:int:min(1)}")]
public string Get(int id)
{
return "Success";
}
}
When I move the Get method into a base controller it is returning the contents of the 404 page.
[RoutePrefix("admin/test")]
public class TestController : TestBaseController
{
}
public class TestBaseController : ApiController
{
[Route("{id:int:min(1)}")]
public string Get(int id)
{
return "Success";
}
}
Some more interesting notes:
I can access the action at GET /Test/1. So it is finding it based on the default route still.
When I try to access POST /admin/test, it returns the following JSON
{
"Message":"No HTTP resource was found that matches the request URI 'http://test.com/admin/test'.",
"MessageDetail":"No type was found that matches the controller named 'admin'."
}
Does anyone know of a way to get the routing to work with attributes from a base controller?
Attribute routes cannot be inherited. This was a deliberate design decision. We didn't feel right and didn't see valid scenarios where it would make sense to inherit them.
Could you give a more realistic scenario as to where you would want to use this?
[Update(3/24/2014)]
In the upcoming 5.2 release of MVC Web API, there is going to be an extensibility point called System.Web.Http.Routing.IDirectRouteProvider through which you can enable the inheritance scenario that you are looking for here. You could try this yourself using the latest night builds(documentation on how to use night builds is here)
[Update(7/31/2014)]
Example of how this can be done in Web API 2.2 release:
config.MapHttpAttributeRoutes(new CustomDirectRouteProvider());
//---------
public class CustomDirectRouteProvider : DefaultDirectRouteProvider
{
protected override IReadOnlyList<IDirectRouteFactory>
GetActionRouteFactories(HttpActionDescriptor actionDescriptor)
{
// inherit route attributes decorated on base class controller's actions
return actionDescriptor.GetCustomAttributes<IDirectRouteFactory>
(inherit: true);
}
}
Using Web API 2.2, you can:
public class BaseController : ApiController
{
[Route("{id:int}")]
public string Get(int id)
{
return "Success:" + id;
}
}
[RoutePrefix("api/values")]
public class ValuesController : BaseController
{
}
config.MapHttpAttributeRoutes(new CustomDirectRouteProvider());
public class CustomDirectRouteProvider : DefaultDirectRouteProvider
{
protected override IReadOnlyList<IDirectRouteFactory>
GetActionRouteFactories(HttpActionDescriptor actionDescriptor)
{
return actionDescriptor.GetCustomAttributes<IDirectRouteFactory>
(inherit: true);
}
}
as outlined here: http://www.asp.net/web-api/overview/releases/whats-new-in-aspnet-web-api-22
Got it.
[Route("api/baseuploader/{action}")]
public abstract class BaseUploaderController : ApiController
{
[HttpGet]
public string UploadFile()
{
return "UploadFile";
}
}
[Route("api/values/{action}")]
public class ValuesController : BaseUploaderController
{
[HttpGet]
public string Get(int id)
{
return "value";
}
}
One caveat here is that the route action paramter must be the same as the action name. I could not find a way to get around that. (You cannot rename the route with a RouteAttribute)

Resources