HttpContext is NULL after using DependencyResolver with Ninject - asp.net

I implemented custom IIdentityMessageService class. My implementation simply put messages into database. I use Dependency resolver to create instance of repository class.
public class QueueSmsService : IIdentityMessageService
{
public Task SendAsync(IdentityMessage message)
{
var smsRepository = DependencyResolver.Current.GetService<ISmsRepository>();
Sms smsMessage = new Sms()
{
Priority = (int)MessagePriority.High,
NumberTo = message.Destination,
Body = message.Body
};
return smsRepository.InsertAndSubmitAsync(smsMessage);
}
}
Unfortunately there is a problem with HttpContext being null. Maybe if I inject repository in contructor would solve the problem? Can I somehow inject repository in contructor? Maybe there is another solution to eliminate the HttpContect == null problem? Right now QueueSmsService is created like below in:
var manager = new AppUserManager(new AppUserStore(context.Get<DataContext>()));
manager.RegisterTwoFactorProvider("SMS", new PhoneNumberTokenProvider<User, int>
{
MessageFormat = "Kod autentykujÄ…cy: {0}"
});
manager.EmailService = new QueueEmailService();
manager.SmsService = new QueueSmsService();
HttpContext is used in repository class
public abstract class RepositoryBase<T> : IRepositoryBase<T> where T : class
{
private IDataContext dataContext;
private readonly IHttpContextFactory httpContextFactory;
protected static Logger logger = LogManager.GetCurrentClassLogger();
public RepositoryBase(IDataContext dataContext, IHttpContextFactory httpContext)
{
if (httpContext == null) throw new ArgumentNullException("httpContextFactory");
this.httpContextFactory = httpContext;
this.dataContext = dataContext;
}
(...)
Where the DataContxtFactory is simply
public class HttpContextFactory : IHttpContextFactory
{
public HttpContextBase Create()
{
return new HttpContextWrapper(HttpContext.Current);
}
}
And the error is reported exactly in the code above.

Related

object reference not set to instance of an object issues in unit testing of asp.net mvc

I am the beginner of writing unit tests for asp.net. I created a simple project and try to start my testing journey. However, I met two errors with the same issue:"object reference not set to instance of an object" The first place is in the home controller as below:
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
Here is my test method:
public class HomeControllerUnitTests
{
ILogger<HomeController> _logger;
[Fact]
public void Error_ActionExecutes_ReturnsAViewResult()
{
// Arrange
var homeController = new HomeController(_logger);
// Act
var result = homeController.Error() as ViewResult;
// Assert
Assert.Null(result.ViewData.Model);
}
}
The second place is in the Movie Controller:
public class MoviesController : Controller
{
private readonly MvcMovieContext _context;
public MoviesController(MvcMovieContext context)
{
_context = context;
}
// GET: Movies
public async Task<IActionResult> Index()
{
return View(await _context.Movie.ToListAsync());
}
}
My test method is as below:
public class MoviesControllerUnitTests
{
private Mock<MvcMovieContext> _mock;
[Fact]
public async Task Index_ActionExecutes_ReturnsAViewResult()
{
// Arrange
MoviesController controller = new MoviesController(_mock.Object);
// Act
var result = await controller.Index() as Task<ViewResult>;
// Assert
Assert.IsType<ViewResult>(result);
}
}
Please help me and thanks in advance.
Below the Object reference not set to an instance of an object line there should be an indication about which file and line the error occurred, which helps you to determine which variables are null (but you could also use the debugger).
For the MoviesControllerUnitTests this probably is the _mock variable, so be sure to initialize it as shown in the docs, e.g.:
private Mock<MvcMovieContext> _mock = new Mock<MvcMovieContext>();
For the HomeControllerUnitTests you might need to mock the Activity or set a HttpContext (see e.g. this question).

Forms.context is obsolete.Context is obsolete as of version 2.5,please use a local context instead

I run into this problem:
Forms.context is obsolete.Context is obsolete as of version 2.5,please use a local context instead.
I m trying to login using Azure Active Directory with code below.
Please help.
using Xamarin.Forms;
using myMobile.Service;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System.Threading.Tasks;
[assembly: Dependency(typeof(myMobile.Droid.Authenticator))]
namespace myMobile.Droid
{
class Authenticator: IAuthenticator
{
public async Task<AuthenticationResult> Authenticate(string tenantUrl, string graphResourceUri, string ApplicationID, string returnUri)
{
try
{
var authContext = new AuthenticationContext(tenantUrl);
if (authContext.TokenCache.ReadItems().Any())
authContext = new AuthenticationContext(authContext.TokenCache.ReadItems().FirstOrDefault().Authority);
var authResult = await authContext.AcquireTokenAsync(graphResourceUri, ApplicationID, new Uri(returnUri), new PlatformParameters((Activity)Forms.Context));
return authResult;
}
catch (Exception)
{
return null;
}
}
}
}
// err encountered on this line :(Activity)Forms.Context)
Forms.context is obsolete.Context is obsolete as of version2.5,please use a local context instead.
var authResult = await authContext.AcquireTokenAsync(graphResourceUri, ApplicationID, new Uri(returnUri), new PlatformParameters((Activity)Forms.Context));
//--- Update :
//-------- Login Page:
private async void Login()
{
try
{
var data = await DependencyService.Get<IAuthenticator>()
.Authenticate(AzureSettings.tenanturl, AzureSettings.GraphResourceUri, AzureSettings.ApplicationID, AzureSettings.ReturnUri);
AzureSettings.AuthenticationResult = data;
//NavigateTopage(data);
}
catch (Exception)
{ }
}
}
//--------- in Shared Project :
//-- interface: IAuthenticator
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System.Threading.Tasks;
namespace myMobile.Service
{
public interface IAuthenticator
{
Task<AuthenticationResult> Authenticate(string tenantUrl, string graphResourceUri, string ApplicationID, string returnUri);
}
}
//-------- in Android Project: add
1) Class : Authenticator.cs
using Android.App;
using Android.Content;
using Xamarin.Forms;
using myMobile.Service;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System.Threading.Tasks;
[assembly: Dependency(typeof(myMobile.Droid.Authenticator))]
namespace myMobile.Droid
{
class Authenticator: IAuthenticator
{
private readonly Context _context;
public static void Init(Context context)
{
_context = context; //--error
}
public async Task<AuthenticationResult> Authenticate(string tenantUrl, string graphResourceUri, string ApplicationID, string returnUri)
{
try
{
var authContext = new AuthenticationContext(tenantUrl);
if (authContext.TokenCache.ReadItems().Any())
authContext = new AuthenticationContext(authContext.TokenCache.ReadItems().FirstOrDefault().Authority);
var authResult = await authContext.AcquireTokenAsync(graphResourceUri, ApplicationID, new Uri(returnUri), new PlatformParameters((Activity) _context));
return authResult;
}
catch (Exception)
{
return null;
}
}
}
}
error :
An Object reference is required for non-static field,method or property.Authenticator._context
//------- Class: MainActivity
namespace myMobile.Droid
{
[Activity(Label = "myMobile", Icon = "#mipmap/icon", Theme = "#style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
DependencyService.Get<IAuthenticator>().Init(this); //<-- Error
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App());
}
}
}
Error Message:
IUAthenticator does not contain a definition for Init and no extension method accepting
a first argument of type IAuthenticator
You now have to implement a custom constructor that takes a Context put that in a local variable and use that instead of this for instance new PlatformParameters((Activity)Forms.Context).
For a custom renderer, you can use the solution underneath. Do like this:
public MyControlRenderer : ControlRenderer
{
private readonly Context _context;
public MyControlRenderer(Context context) : base(context)
{
_context = context;
}
}
For a dependency service like yours, you will have to find a way to supply the Context. Since Xamarin.Forms uses a single activity, you can get away with some kind of init method.
Add this to your code:
public class MyService : IMyService
{
private static Context _context;
public static void Init(Context context)
{
_context = context;
}
}
Now call the Init from your MainActivity and you should be good after that. So do: DependencyService.Get<IMyService>().Init(this);
For other people coming across this for multiple activities, please refer to the documentation here: https://www.davidbritch.com/2017/11/xamarinforms-25-and-local-context-on.html that is what this is inspired on.

NHibernate in Web API ASP.NET: No session bound to the current context

I'm new to NHibernate and trying to use it in ASP.NET WEB API. Firstly I used it successfully with one table named "Category" which the controller class is as follow:
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using TestMVCProject.Web.Api.HttpFetchers;
using TestMVCProject.Web.Api.Models;
using TestMVCProject.Web.Api.TypeMappers;
using TestMVCProject.Web.Common;
//using TestMVCProject.Web.Common.Security;
using NHibernate;
namespace TestMVCProject.Web.Api.Controllers
{
[LoggingNHibernateSession]
public class CategoryController : ApiController
{
private readonly ISession _session;
private readonly ICategoryMapper _categoryMapper;
private readonly IHttpCategoryFetcher _categoryFetcher;
public CategoryController(
ISession session,
ICategoryMapper categoryMapper,
IHttpCategoryFetcher categoryFetcher)
{
_session = session;
_categoryMapper = categoryMapper;
_categoryFetcher = categoryFetcher;
}
public IEnumerable<Category> Get()
{
return _session
.QueryOver<Data.Model.Category>()
.List()
.Select(_categoryMapper.CreateCategory)
.ToList();
}
public Category Get(long id)
{
var category = _categoryFetcher.GetCategory(id);
return _categoryMapper.CreateCategory(category);
}
public HttpResponseMessage Post(HttpRequestMessage request, Category category)
{
var modelCategory = new Data.Model.Category
{
Description = category.Description,
CategoryName = category.CategoryName
};
_session.Save(modelCategory);
var newCategory = _categoryMapper.CreateCategory(modelCategory);
//var href = newCategory.Links.First(x => x.Rel == "self").Href;
var response = request.CreateResponse(HttpStatusCode.Created, newCategory);
//response.Headers.Add("Location", href);
return response;
}
public HttpResponseMessage Delete()
{
var categories = _session.QueryOver<Data.Model.Category>().List();
foreach (var category in categories)
{
_session.Delete(category);
}
return new HttpResponseMessage(HttpStatusCode.OK);
}
public HttpResponseMessage Delete(long id)
{
var category = _session.Get<Data.Model.Category>(id);
if (category != null)
{
_session.Delete(category);
}
return new HttpResponseMessage(HttpStatusCode.OK);
}
public Category Put(long id, Category category)
{
var modelCateogry = _categoryFetcher.GetCategory(id);
modelCateogry.CategoryName = category.CategoryName;
modelCateogry.Description = category.Description;
_session.SaveOrUpdate(modelCateogry);
return _categoryMapper.CreateCategory(modelCateogry);
}
}
}
But when I add The "Product" table which has a foreign key of the Category table, the product controller doesn't work and throws below exception:
No session bound to the current context
ProductController class is as follow:
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using TestMVCProject.Web.Api.HttpFetchers;
using TestMVCProject.Web.Api.Models;
using TestMVCProject.Web.Api.TypeMappers;
using TestMVCProject.Web.Common;
//using TestMVCProject.Web.Common.Security;
using NHibernate;
namespace TestMVCProject.Web.Api.Controllers
{
[LoggingNHibernateSession]
public class ProductController : ApiController
{
private readonly ISession _session;
private readonly IProductMapper _productMapper;
private readonly IHttpProductFetcher _productFetcher;
public ProductController(
ISession session,
IProductMapper productMapper,
IHttpProductFetcher productFetcher)
{
_session = session;
_productMapper = productMapper;
_productFetcher = productFetcher;
}
public IEnumerable<Product> Get()
{
return _session
.QueryOver<Data.Model.Product>()
.List()
.Select(_productMapper.CreateProduct)
.ToList();
}
public Product Get(long id)
{
var product = _productFetcher.GetProduct(id);
return _productMapper.CreateProduct(product);
}
public HttpResponseMessage Post(HttpRequestMessage request, Product product)
{
var modelProduct = new Data.Model.Product
{
Description = product.Description,
ProductName = product.ProductName
};
_session.Save(modelProduct);
var newProduct = _productMapper.CreateProduct(modelProduct);
//var href = newproduct.Links.First(x => x.Rel == "self").Href;
var response = request.CreateResponse(HttpStatusCode.Created, newProduct);
//response.Headers.Add("Location", href);
return response;
}
public HttpResponseMessage Delete()
{
var categories = _session.QueryOver<Data.Model.Product>().List();
foreach (var product in categories)
{
_session.Delete(product);
}
return new HttpResponseMessage(HttpStatusCode.OK);
}
public HttpResponseMessage Delete(long id)
{
var product = _session.Get<Data.Model.Product>(id);
if (product != null)
{
_session.Delete(product);
}
return new HttpResponseMessage(HttpStatusCode.OK);
}
public Product Put(long id, Product product)
{
var modelProduct = _productFetcher.GetProduct(id);
modelProduct.ProductName = product.ProductName;
modelProduct.Description = product.Description;
_session.SaveOrUpdate(modelProduct);
return _productMapper.CreateProduct(modelProduct);
}
}
}
and the mapping class for Product table:
using TestMVCProject.Data.Model;
using FluentNHibernate.Mapping;
namespace TestMVCProject.Data.SqlServer.Mapping
{
public class ProductMap : ClassMap<Product>
{
public ProductMap()
{
Id(x => x.ProductId);
Map(x => x.ProductName).Not.Nullable();
Map(x => x.Description).Nullable();
Map(x => x.CreateDate).Not.Nullable();
Map(x => x.Price).Not.Nullable();
References<Category>(x => x.CategoryId).Not.Nullable();
}
}
}
What is wrong?
Your snippets are missing the way, how the ISessionFactory is created and how ISession is passed into your controllers... You should follow this really comprehensive story (by Piotr Walat):
NHibernate session management in ASP.NET Web API
Where you can see that we, can use 2.3. Contextual Sessions:
NHibernate.Context.WebSessionContext - stores the current session in HttpContext. You are responsible to bind and unbind an ISession instance with static methods of class CurrentSessionContext.
The configuration
<session-factory>
..
<property name="current_session_context_class">web</property>
</session-factory>
In the article you can check that we need at the app start initialize factory (just an extract):
public class WebApiApplication : System.Web.HttpApplication
{
private void InitializeSessionFactory() { ... }
protected void Application_Start()
{
InitializeSessionFactory();
...
Next we should create some AOP filter (just an extract):
public class NhSessionManagementAttribute : ActionFilterAttribute
{
...
public override void OnActionExecuting(HttpActionContext actionContext)
{
// init session
var session = SessionFactory.OpenSession();
...
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
// close session
...
session = CurrentSessionContext.Unbind(SessionFactory);
}
For more details check the source mentioned above
Your approach of passing the session to the constructor of the controller factory does not seems to be working, there are a few ways to do this
1. Using dependency injection
If you are using a dependency injection framework, you have to configure controller so that it's constructed per request, it should looks like this (I have used the code for Ninject)
Step 1 - setup the session for injection
public class DIModule : NinjectModule
{
public override void Load()
{
this.Bind<ISessionFactory>()... bind to the session factory
this.Bind<ISession>().ToMethod(ctx => ctx.Kernel.Get<ISessionFactory>().OpenSession())
.InRequestScope();
}
private ISession CreateSessionProxy(IContext ctx)
{
var session = (ISession)this.proxyGenerator.CreateInterfaceProxyWithoutTarget(typeof(ISession), new[] { typeof(ISessionImplementor) }, ctx.Kernel.Get<SessionInterceptor>());
return session;
}
}
Step 2 - Create the controller factory so that it will inject the session when resolving
public class NinjectControllerFactory : DefaultControllerFactory, IDependencyResolver
{
private IDependencyResolver _defaultResolver;
public NinjectControllerFactory(IDependencyResolver defaultResolver)
{
_defaultResolver = defaultResolver;
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
return controllerType == null
? null
: (IController)DependencyKernel.Kernel.Get(controllerType);
}
public IDependencyScope BeginScope()
{
return this;
}
public object GetService(Type serviceType)
{
try
{
return DependencyKernel.Kernel.Get(serviceType);
}
catch (Exception)
{
return GetService(serviceType);
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
object item = DependencyKernel.Kernel.Get(serviceType);
return new List<object>() {item};
}
catch (Exception)
{
return GetServices(serviceType);
}
}
public void Dispose()
{
}
}
Step 3 - Register the controller factory
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
var factory = new NinjectControllerFactory(GlobalConfiguration.Configuration.DependencyResolver);
ControllerBuilder.Current.SetControllerFactory(factory);
GlobalConfiguration.Configuration.DependencyResolver = factory;
}
}
Now what will happen is that when your controller is created it will inject the a new NH session per each request.
2. Using a filter
This is much simpler, but you may need to change your controllers a bit this to work,
Step 1 - Setup the correct session context for the factory
_sessionFactory = CreateConfiguration()
.ExposeConfiguration(c => c.SetProperty("current_session_context_class","web"))
.BuildSessionFactory();
Step 2 - Create the filter
public class SessionPerRequestAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
var session = SessionFactory.OpenSession();
NHibernate.Context.CurrentSessionContext.Bind(session);
base.OnActionExecuting(actionContext);
}
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
var session = SessionFactory.GetCurrentSession();
session.Flush();
session.Clear();
session.Close();
base.OnActionExecuted(actionExecutedContext);
}
}
Step 3 - Register the filter in global configuration
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//Do other config here
config.Filters.Add(new SessionPerRequestAttribute());
}
}
Step 4 - Modify your controller a bit,
public class CategoryController : ApiController
{
private readonly ICategoryMapper _categoryMapper;
private readonly IHttpCategoryFetcher _categoryFetcher;
public CategoryController(
ICategoryMapper categoryMapper,
IHttpCategoryFetcher categoryFetcher)
{
_categoryMapper = categoryMapper;
_categoryFetcher = categoryFetcher;
}
public IEnumerable<Category> Get()
{
var session = SessionFactory.GetCurrentSession();
return session
.QueryOver<Data.Model.Category>()
.List()
.Select(_categoryMapper.CreateCategory)
.ToList();
}
}
Here what happens is, when a request comes it will create a new session and it is bound to the request context and same is used for the web API method.

Dependency Inject asp.net MVC4 Ninject

This is my first project using Ninject and MVC, I`m trying to implement.
But I'm getting this error:
Error activating ISessionFactory
No matching bindings are available, and the type is not self-bindable.
Activation path:
Injection of dependency ISessionFactory into parameter session of constructor of type PersonRepository
Injection of dependency IPersonRepository into parameter personsRepository of constructor of type HomeController
Request for HomeController
My Repository :
public class PersonRepository : IPersonRepository
{
private ISession openSession;
private ISessionFactory session;
public PersonRepository(ISessionFactory session)
{
this.openSession = session.OpenSession();
this.session = session;
}
public void CreatePerson(Person person)
{
openSession = NhibernateUtilities.OpenIfClosed(session, openSession);
openSession.SaveOrUpdate(person);
}
My Controller :
public class HomeController : Controller
{
private readonly IPersonRepository personsRepository;
public HomeController(IPersonRepository personsRepository)
{
this.personsRepository = personsRepository;
}
public ActionResult Index()
{
Person test = new Person()
{
Id = 1,
Name = "teste",
Surname = "teste",
Nickname = "teste",
Age = 25,
Division = "teste",
Email = "teste",
Lane = "teste"
};
personsRepository.CreatePerson(test);
return View();
}
Global.asax :
public class MvcApplication : NinjectHttpApplication
{
protected override IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
kernel.Bind<IPersonRepository>().To<PersonRepository>();
return kernel;
}
protected override void OnApplicationStarted()
{
base.OnApplicationStarted();
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
I'm using Fluent Nhibernate.
Ref : Need help understanding how Ninject is getting a Nhibernate SessionFactory instance into a UnitOfWork?
You need to bind the session factory
Bind<ISession>().ToProvider<SessionProvider>().InRequestScope();
And use ISession in the repo constructor
public class PersonRepository : IPersonRepository
{
private ISession session;
public PersonRepository(ISession session)
{
this.session = session;
}
...

How do you mock ServiceStack ISession using Moq and StructureMap?

I'm using ServiceStack / StructureMap / Moq. The service makes a call to Session, which is type ServiceStack.CacheAccess.ISession. For unit tests, I created a Mock object using Moq, and added it to the StructureMap configuration:
protected Mock<ISession> sessionMock = new Mock<ISession>();
ObjectFactory.Configure(
cfg =>
{
cfg.For<ISession>().Use(sessionMock.Object);
However, I was not surprised when the Session object was null -- I'm pretty sure I'm leaving out a step. What else do I need to do to fill my Session property with a mock object?
[EDIT] Here's a simple test scenario
Code to test. Simple request / service
[Route("getKey/{key}")]
public class MyRequest:IReturn<string>
{
public string Key { get; set; }
}
public class MyService:Service
{
public string Get(MyRequest request)
{
return (string) Session[request.Key];
}
}
The base test class and MockSession classes
// test base class
public abstract class MyTestBase : TestBase
{
protected IRestClient Client { get; set; }
protected override void Configure(Container container)
{
// this code is never reached under any of my scenarios below
container.Adapter = new StructureMapContainerAdapter();
ObjectFactory.Initialize(
cfg =>
{
cfg.For<ISession>().Singleton().Use<MockSession>();
});
}
}
public class MockSession : ISession
{
private Dictionary<string, object> m_SessionStorage = new Dictionary<string, object>();
public void Set<T>(string key, T value)
{
m_SessionStorage[key] = value;
}
public T Get<T>(string key)
{
return (T)m_SessionStorage[key];
}
public object this[string key]
{
get { return m_SessionStorage[key]; }
set { m_SessionStorage[key] = value; }
}
}
And tests. See comments for where I'm seeing the failure. I didn't really expect versions 1 & 2 to work, but hoped version 3 would.
[TestFixture]
public class When_getting_a_session_value:MyTestBase
{
[Test]
public void Test_version_1()
{
var session = ObjectFactory.GetInstance<MockSession>();
session["key1"] = "Test";
var request = new MyRequest {Key = "key1"};
var client = new MyService(); // generally works fine, except for things like Session
var result = client.Get(request); // throws NRE inside MyService
result.ShouldEqual("Test");
}
[Test]
public void Test_version_2()
{
var session = ObjectFactory.GetInstance<MockSession>();
session["key1"] = "Test";
var request = new MyRequest {Key = "key1"};
var client = ObjectFactory.GetInstance<MyService>();
var result = client.Get(request); // throws NRE inside MyService
result.ShouldEqual("Test");
}
[Test]
public void Test_version_3()
{
var session = ObjectFactory.GetInstance<MockSession>();
session["key1"] = "Test";
var request = new MyRequest {Key = "key1"};
var client = CreateNewRestClient();
var result = client.Get(request); // throws NotImplementedException here
result.ShouldEqual("Test");
}
}
It looks like you're trying to create unit tests, but you're using an AppHost like you wound an Integration test. See this previous answer for differences between the two and docs on Testing.
You can mock the Session by registering an instance in Request.Items[Keywords.Session], e.g:
[Test]
public void Can_mock_IntegrationTest_Session_with_Request()
{
using var appHost = new BasicAppHost(typeof(MyService).Assembly).Init();
var req = new MockHttpRequest();
req.Items[Keywords.Session] = new AuthUserSession {
UserName = "Mocked"
};
using var service = HostContext.ResolveService<MyService>(req);
Assert.That(service.GetSession().UserName, Is.EqualTo("Mocked"));
}
Otherwise if you set AppHost.TestMode=true ServiceStack will return the IAuthSession that's registered in your IOC, e.g:
[Test]
public void Can_mock_UnitTest_Session_with_IOC()
{
using var appHost = new BasicAppHost
{
TestMode = true,
ConfigureContainer = container =>
{
container.Register<IAuthSession>(c => new AuthUserSession {
UserName = "Mocked",
});
}
}.Init();
var service = new MyService {
Request = new MockHttpRequest()
};
Assert.That(service.GetSession().UserName, Is.EqualTo("Mocked"));
}

Resources