在我的asp.net core 2应用程序中,我有一个静态类来处理与会话的一些交互。例如:
AsyncRestTemplate
我还在会话对象中添加了一些扩展方法:
ListenableFuture
更新:这就是我试图模仿的方式:
public static class BookManager
{
private const string Key = "Books";
public static HttpContextAccessor ContextAccessor => new HttpContextAccessor();
public static void AddBooksToContainer(IEnumerable<BookViewModel> books)
{
ContextAccessor.HttpContext.Session.Set(Key, books);
}
public static IEnumerable<BookViewModel> GetBooks()
{
return ContextAccessor.HttpContext.Session.Get<IEnumerable<BookViewModel>>(Key);
}
}
我得到的错误:
public static class SessionExtensions
{
public static void Set<T>(this ISession session, string key, IEnumerable<T> value)
{
session.SetString(key, JsonConvert.SerializeObject(value));
}
public static void Set<T>(this ISession session, string key, T value)
{
session.SetString(key, JsonConvert.SerializeObject(value));
}
public static T Get<T>(this ISession session, string key)
{
var value = session.GetString(key);
return value == null ? default(T) :
JsonConvert.DeserializeObject<T>(value);
}
}
问题是我尝试过很多方法来模拟会话及其扩展方法,但我还没有得到任何结果。很多方法都适用于.netframework而不是核心。
我使用xunit进行测试,使用Moq库来模拟对象。请告诉我如何模拟会话及其扩展方法。欣赏它。
答案 0 :(得分:1)
问题与.NET Core无关,是模拟库的限制,你不能用Moq模拟扩展方法。
这可能会有所帮助:Mocking Extension Methods with Moq
答案 1 :(得分:1)
取决于抽象而非结核。创建一个Factory方法,为您提供IHttpContextAccessor
抽象。
public static class BookManager {
private const string Key = "Books";
public static Func<IHttpContextAccessor> ContextAccessor = () => new HttpContextAccessor();
public static void AddBooksToContainer(IEnumerable<BookViewModel> books) {
ContextAccessor().HttpContext.Session.Set(Key, books);
}
public static IEnumerable<BookViewModel> GetBooks() {
return ContextAccessor().HttpContext.Session.Get<IEnumerable<BookViewModel>>(Key);
}
}
这将允许您在使用mock进行测试时替换抽象。
//Arrange
var mock = mock.Of<IHttpContextAccessor>();
BookManager.ContextAccessor = () => {
return mock.Object;
};
//...
更好的是,如果这位经理只需要会话,那么不要暴露超出需要的数量。
public static class BookManager {
private const string Key = "Books";
public static Func<ISession> Session = () => new HttpContextAccessor().HttpContext.Session;
public static void AddBooksToContainer(IEnumerable<BookViewModel> books) {
Session().Set(Key, books);
}
public static IEnumerable<BookViewModel> GetBooks() {
return Session().Get<IEnumerable<BookViewModel>>(Key);
}
}
所以现在只需要为测试模拟显式依赖项。
根据ISession Extensions source code GetString
和SetString
也是扩展方法
您需要模拟ISession.TryGetValue
和ISession.Set
//Arrange
var mock = Mock.Of<ISession>();
BookManager.Session = () => {
return mock;
};
var value = Encoding.UTF8.GetBytes("[{some books json strings here}]");
Mock.Get(mock).Setup(_ => _.TryGetValue("Books", out value))
.Returns(true);
//Act
var books = BookManager.GetBooks();
//...