我正在为我的方法创建单元测试
[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);
}
我的测试方法是
[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());
}
我的会话信息类如下,我在会话适配器中使用的这个类
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; }
}
我无法实例化SessionAdapter
。我该如何对此进行单元测试?
我的界面和sessionadapter类如下所示
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();
}
}
我的测试用例与下面的答案相同
[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);
}
代码更新。请找到我用于SessionAdapter类和ISessionAdapter接口的以下代码以及implementation.please以正确的方式给出您的建议。
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();
}
答案 0 :(得分:4)
抽象外部依赖并将其注入控制器。只要它保持静止,那么在测试方面没有什么可做的
抽象可以看起来像这样
public interface ISessionAdapterService {
int Id { get; }
string DisplayName { get; set; }
}
具有以下实现。
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需要使用抽象作为依赖
[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);
}
假设sessionAdapterService
是注入ISessionAdapterService
单元测试现在可以模拟外部依赖关系并将其注入控制器。
[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);
}
更新。
基于您的评论更新了SessionInfo类的抽象
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; }
}
我还建议你检查模型设计。它非常脆弱,迫使会话信息类与实现问题紧密结合。