Reputation: 61
I am creating unit test for my method
[Authorize]
[HttpPost]
public async Task<JsonResult> UpdateDisplayName(string displayname)
{
bool status = _myProfileService.UpdateDisplayName(displayname, SessionAdapter.Instance._userDetailsViewModel.id);
if (status)
SessionAdapter.Instance._userDetailsViewModel.display_name = displayname;
return Json(new { status = status, displayname = displayname }, JsonRequestBehavior.AllowGet);
}
and my test method is
[TestMethod]
public async Task UpdateDisplayName_Test()
{
//Arrange
var controller = new HomeController(userServiceMock.Object, myProfileServiceMock.Object);
string displayName = "display";
const string expected = "{ status = False, displayname = display }";
myProfileServiceMock.Setup(m => m.UpdateDisplayName(It.IsAny<string>(), 1)).Returns(false);
//var controllerContextMock = new Mock<ControllerContext>();
//Act
var result = await controller.UpdateDisplayName(displayName) as JsonResult;
//Assert
Assert.AreEqual(expected, result.Data.ToString());
}
My Session Info Class is below, this class i am using in session adapter
public class SessionInfo
{
public string Id { set; get; }
public string Email { set; get; }
public string UserName { set; get; }
public UserDetailsViewModel _userDetailsViewModel { set; get; }
public string permission { set; get; }
//public string organization { set; get; }
public OrganizationViewModels Organization { set; get; }
public List<UserTeamModels> teams { set; get; }
public string status { set; get; }
public string role { set; get; }
public List<string> roles { set; get; }
}
I am unable to instantiate SessionAdapter
. How can I unit test this?
My Interface and sessionadapter class were looks like below
public interface ISessionAdapterService
{
void Clear();
void Abandon();
bool DoesSessionExists { get; }
SessionInfo Instance { get; set; }
}
public class SessionAdapterService : ISessionAdapterService
{
private string sessionKey = "sessionInfoKey";
public bool DoesSessionExists
{
get
{
return HttpContext.Current.Session[sessionKey] == null ? false : true;
}
}
public SessionInfo Instance
{
get
{
return HttpContext.Current.Session[sessionKey] == null ? null : (SessionInfo)HttpContext.Current.Session[sessionKey];
}
set
{
HttpContext.Current.Session[sessionKey] = value;
}
}
public void Abandon()
{
HttpContext.Current.Session.Abandon();
HttpContext.Current.Session[sessionKey] = null;
}
public void Clear()
{
HttpContext.Current.Session.Clear();
}
}
My test case is same as the answer below
[TestMethod]
public async Task UpdateDisplayName_Test() {
//Arrange
var mySessionAdaptorService = new Mock<ISessionAdaptorService>();
var controller = new HomeController(userServiceMock.Object, myProfileServiceMock.Object, mySessionAdaptorService.Object);
var displayName = "display";
var status = false;
var id = 1;
myProfileServiceMock.Setup(m => m.UpdateDisplayName(It.IsAny<string>(), id)).Returns(status);
mySessionAdaptorService.Setup(m => m.Instance.Id).Returns(id);
//Act
var result = await controller.UpdateDisplayName(displayName) as JsonResult;
//Assert
Assert.IsNotNull(result);
}
Code Update. Please find the below code i used for SessionAdapter class and ISessionAdapter Interface and also implementation.please give your suggestions is this correct way.
public interface ISessionInfo
{
string Id { set; get; }
string Email { set; get; }
string UserName { set; get; }
UserDetailsViewModel _userDetailsViewModel { set; get; }
string permission { set; get; }
OrganizationViewModels Organization { set; get; }
List<UserTeamModels> teams { set; get; }
string status { set; get; }
string role { set; get; }
List<string> roles { set; get; }
}
public class SessionInfo : ISessionInfo
{
public string Id { set; get; }
public string Email { set; get; }
public string UserName { set; get; }
public UserDetailsViewModel _userDetailsViewModel { set; get; }
public string permission { set; get; }
//public string organization { set; get; }
public OrganizationViewModels Organization { set; get; }
public List<UserTeamModels> teams { set; get; }
public string status { set; get; }
public string role { set; get; }
public List<string> roles { set; get; }
}
public interface ISessionAdapter
{
void Clear();
void Abandon();
bool DoesSessionExists { get; }
ISessionInfo Instance { get; set; }
}
public class SessionAdapter : ISessionAdapter
{
private string sessionKey = "sessionInfoKey";
public bool DoesSessionExists
{
get
{
return HttpContext.Current.Session[sessionKey] == null ? false : true;
}
}
public ISessionInfo Instance
{
get
{
return HttpContext.Current.Session[sessionKey] == null ? null : (SessionInfo)HttpContext.Current.Session[sessionKey];
}
set
{
HttpContext.Current.Session[sessionKey] = value;
}
}
public void Abandon()
{
HttpContext.Current.Session.Abandon();
HttpContext.Current.Session[sessionKey] = null;
}
public void Clear()
{
HttpContext.Current.Session.Clear();
}
Upvotes: 2
Views: 92
Reputation: 247088
Abstract external dependency and inject it into the controller. As long as it remains static there isn't much else to do about it test-wise
An abstraction can look like this
public interface ISessionAdapterService {
int Id { get; }
string DisplayName { get; set; }
}
with the following implementation.
public class SessionAdapterService : ISessionAdapterService {
public string DisplayName {
get { return SessionAdapter.Instance._userDetailsViewModel.display_name; }
set { SessionAdapter.Instance._userDetailsViewModel.display_name = value; }
}
public int Id {
get { return SessionAdapter.Instance._userDetailsViewModel.id; }
}
}
Controller would need to use abstraction as dependency
[Authorize]
[HttpPost]
public async Task<JsonResult> UpdateDisplayName(string displayname) {
bool status = _myProfileService.UpdateDisplayName(displayname, sessionAdapterService.Id);
if (status)
sessionAdapterService.DisplayName = displayname;
return Json(new { status = status, displayname = displayname }, JsonRequestBehavior.AllowGet);
}
Assuming sessionAdapterService
is an injected ISessionAdapterService
The unit test can now mock the external dependency and inject it into the controller.
[TestMethod]
public async Task UpdateDisplayName_Test() {
//Arrange
var mySessionAdaptorService = new Mock<ISessionAdaptorService>();
var controller = new HomeController(userServiceMock.Object, myProfileServiceMock.Object, mySessionAdaptorService.Object);
var displayName = "display";
var status = false;
var id = 1;
myProfileServiceMock.Setup(m => m.UpdateDisplayName(It.IsAny<string>(), id)).Returns(status);
mySessionAdaptorService.Setup(m => m.Id).Returns(id);
//Act
var result = await controller.UpdateDisplayName(displayName) as JsonResult;
//Assert
Assert.IsNotNull(result);
dynamic data = result.Data;
Assert.IsNotNull(data);
Assert.AreEqual(displayName, (string)data.displayname);
Assert.AreEqual(status, (bool)data.status);
}
UPDATE.
based on your comments Updated abstraction of the SessionInfo class
public interface ISessionInfo {
string Id { set; get; }
string Email { set; get; }
string UserName { set; get; }
UserDetailsViewModel _userDetailsViewModel { set; get; }
string permission { set; get; }
OrganizationViewModels Organization { set; get; }
List<UserTeamModels> teams { set; get; }
string status { set; get; }
string role { set; get; }
List<string> roles { set; get; }
}
public class SessionInfo : ISessionInfo { ... }
public interface ISessionAdapterService {
void Clear();
void Abandon();
bool DoesSessionExists { get; }
ISessionInfo Instance { get; set; }
}
I would also advise you to review you model design. It is very brittle and forces the session info class to be tightly coupled to implementation concerns.
Upvotes: 4