Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Moq单元测试C#设置Mockobjects并进行验证?_C#_Asp.net Mvc_Dependency Injection_Moq_Memorycache - Fatal编程技术网

如何使用Moq单元测试C#设置Mockobjects并进行验证?

如何使用Moq单元测试C#设置Mockobjects并进行验证?,c#,asp.net-mvc,dependency-injection,moq,memorycache,C#,Asp.net Mvc,Dependency Injection,Moq,Memorycache,我的缓存类如下所示: public class InMemoryCache : ICache { private readonly ObjectCache _objCache = MemoryCache.Default; public void Insert<T>(string cacheKey, T value) { _objCache.Add(cacheKey, value, DateTimeOffset.MaxValue)

我的缓存类如下所示:

public class InMemoryCache : ICache
{
    private readonly ObjectCache _objCache = MemoryCache.Default;       

    public void Insert<T>(string cacheKey, T value)
    {
        _objCache.Add(cacheKey, value, DateTimeOffset.MaxValue);
    }
    public T Get<T>(string cacheKey)
    {
        if (cacheKey != null)
            return (T)Convert.ChangeType(_objCache.Get(cacheKey), typeof(T));
        else
            return default(T);
    }
    public bool Exists<T>(string cacheKey)
    {
        return _objCache.Get(cacheKey) != null;
    }
}
内存缓存中的公共类:ICache
{
私有只读对象缓存_objCache=MemoryCache.Default;
公共void插入(字符串缓存键,T值)
{
_Add(cacheKey,value,DateTimeOffset.MaxValue);
}
公共T获取(字符串缓存键)
{
if(cacheKey!=null)
return(T)Convert.ChangeType(_objCache.Get(cacheKey),typeof(T));
其他的
返回默认值(T);
}
公共bool存在(字符串cacheKey)
{
return _objCache.Get(cacheKey)!=null;
}
}
我的界面是

 public interface ICache
 {
    void Insert<T>(string cacheKey, T value);
    T Get<T>(string cacheKey);
    bool Exists<T>(string cacheKey);        
 }
公共接口ICache
{
无效插入(字符串缓存键,T值);
T Get(字符串缓存键);
bool存在(字符串缓存键);
}
我正在使用CacheFactory调用InMemoryCache类:

public class CacheFactory
{
    public static ICache Cache { get; set; }

    public static void Insert<T>(string cacheKey, T value)
    {
        Cache.Insert<T>(cacheKey, value);
    }

    public static T Get<T>(string cacheKey)
    {
        return Cache.Get<T>(cacheKey);
    }

    public static bool Exists<T>(string cacheKey)
    {
        return Cache.Get<T>(cacheKey) != null;
    }
}
公共类缓存工厂
{
公共静态ICache缓存{get;set;}
公共静态void插入(字符串缓存键,T值)
{
Cache.Insert(cacheKey,value);
}
公共静态T Get(字符串缓存键)
{
返回Cache.Get(cacheKey);
}
存在公共静态bool(字符串cacheKey)
{
返回Cache.Get(cacheKey)!=null;
}
}
我尝试了下面这样的模拟对象,但无法得到结果

 [Fact()]
    public void CacheManager_Insert_Test()
    {
        string cacheKey = "GradeList";

        Mock<ICache> mockObject = new Mock<ICache>();
        List<Grade> grades = new List<Grade>
        {
            new Grade() {Id = 1, Name = "A*"},
            new Grade() {Id = 2, Name = "A"},
            new Grade() {Id = 3, Name = "B"},
            new Grade() {Id = 4, Name = "C"},
            new Grade() {Id = 5, Name = "D"},
            new Grade() {Id = 6, Name = "E"}
        };

        var mockedObjectCache = new Mock<ICache>();
        // Setup mock's Set method

        mockedObjectCache.Setup(m => m.Insert(cacheKey, grades));

       // How to get the Mocked data and verify it here

    }
[Fact()]
public void CacheManager_Insert_Test()
{
string cacheKey=“成绩表”;
Mock mockObject=new Mock();
列表等级=新列表
{
新等级(){Id=1,Name=“A*”},
新等级(){Id=2,Name=“A”},
新等级(){Id=3,Name=“B”},
新等级(){Id=4,Name=“C”},
新等级(){Id=5,Name=“D”},
新等级(){Id=6,Name=“E”}
};
var mockedObjectCache=new Mock();
//设置mock的Set方法
mockedObjectCache.Setup(m=>m.Insert(cacheKey,grades));
//如何获取模拟数据并在此处进行验证
}
有人能检查一下我插入缓存的数据是否正确吗?另外,如何在单元测试Moq中验证缓存数据?我不熟悉单元测试

我无法验证,因为我正在将数据插入到实现类中的对象缓存中,但正在模拟接口。我想如果我能把两者都联系起来,那可能是在验证。不确定,这只是我的猜测

更新的场景 考虑使用另一个名为“Convertor”的类,该类根据缓存中的等级ID检索等级名称

public class Convertor
{ 
    // Gets Grade ID and Displays Grade Name
    public string GetGradeName(int gradeId)
    {
        var gradeList = CacheFactory.Cache.Get<List<Grade>>(CacheKeys.Grades);
        return gradeList.Where(x => x.Id == gradeId).Select(x => x.Name).FirstOrDefault();
    }
}
公共类转换器
{ 
//获取等级ID并显示等级名称
公共字符串GetGradeName(int gradeId)
{
var gradeList=CacheFactory.Cache.Get(CacheKeys.Grades);
返回gradeList.Where(x=>x.Id==gradeId)。选择(x=>x.Name)。FirstOrDefault();
}
}

对于这种情况,我如何验证这一点?由于此方法使用缓存来检索值,因此我不确定如何在此处使用mock。

您似乎误解了mock的用法。使用mock的原因是测试依赖类而不必担心依赖性

假设您有以下课程:

public class MyDependentClass {
    private readonly ICache _cache;
    public MyDependentClass(ICache cache)
    {
        _cache = cache;
    }

    public int CountGradesInCache()
    {
        // Behavior depends on what's in the _cache object
        return _cache.Get<List<Grade>>("GradeList").Count;
    }
}
我们模拟
ICache
,使用依赖类所依赖的缓存键“GradeList”返回6个等级。我们现在可以测试
MyDependentClass
上的方法是否正确返回缓存中的计数。同样,您可以在缓存返回空列表或
null
的情况下进行测试,以检查依赖类的行为在所有情况下是否正确

在您的示例中,似乎要测试内存缓存中的
本身,在这种情况下,您不想模拟任何东西。我只需编写如下测试:

var cache = new InMemoryCache();
var list = new List<Grade> { ... };
var cache.Insert("GradeList", list);

var cachedList = cache.Get<List<Grade>>("GradeList");

// Assert that the list retrieved from cache has the expected values.

现在,您可以模拟
ICache
并测试
转换器的功能,就像我上面描述的那样。

您似乎误解了模拟的用法。使用mock的原因是测试依赖类而不必担心依赖性

假设您有以下课程:

public class MyDependentClass {
    private readonly ICache _cache;
    public MyDependentClass(ICache cache)
    {
        _cache = cache;
    }

    public int CountGradesInCache()
    {
        // Behavior depends on what's in the _cache object
        return _cache.Get<List<Grade>>("GradeList").Count;
    }
}
我们模拟
ICache
,使用依赖类所依赖的缓存键“GradeList”返回6个等级。我们现在可以测试
MyDependentClass
上的方法是否正确返回缓存中的计数。同样,您可以在缓存返回空列表或
null
的情况下进行测试,以检查依赖类的行为在所有情况下是否正确

在您的示例中,似乎要测试内存缓存中的
本身,在这种情况下,您不想模拟任何东西。我只需编写如下测试:

var cache = new InMemoryCache();
var list = new List<Grade> { ... };
var cache.Insert("GradeList", list);

var cachedList = cache.Get<List<Grade>>("GradeList");

// Assert that the list retrieved from cache has the expected values.

现在,您可以模拟
ICache
并测试
转换器的功能,就像我上面描述的那样。

您似乎对这些概念感到困惑

如果您想(单元)测试InMemoryCache类的Insert方法,您肯定不应该模拟InMemoryCache

模拟用于您要测试的类中使用的第三方类

事实上,您的insert方法中还有一个依赖项:

private readonly ObjectCache _objCache = MemoryCache.Default;
因此,您应该以某种方式模拟ObjectCache实例

但这次ObjectCache必须从相关接口继承,以便在Moq库中使用,即IOObjectCache

你应该使用:

var mockObjectCache = new Mock<IObjectCache>();
...

//Verifying:
mockObjectCache.Verify(cache => cache.Add(It.IsAny<string>())).Should().Be(true);
var mockObjectCache=new Mock();
...
//验证:
mockObjectCache.Verify(cache=>cache.Add(It.IsAny()).Should().Be(true);

然而,ObjectCache类是从IEnumerable和IEnumerable>继承的,所以您不能直接模拟它。如果您真的需要模拟,您应该使用桥接接口(反腐败层)。

您似乎对这些概念感到困惑

如果您想(单元)测试InMemoryCache类的Insert方法,您肯定不应该模拟InMemoryCache

模拟用于您要测试的类中使用的第三方类

事实上你有一个