我非常感谢Moq的Loose模拟行为,在没有设定期望时返回默认值.这很方便,可以节省代码,也可以作为一种安全措施:在单元测试期间不会无意中调用依赖关系(只要它们是虚拟的).
但是,当被测方法恰好是虚拟时,我对如何保持这些好处感到困惑.
在这种情况下,我确实想要为这一个方法调用真正的代码,同时仍然对该类的其余部分进行松散的模拟.
我在搜索中找到的就是我可以设置mock.CallBase = true以确保调用该方法.但是,这会影响整个班级.我不想那样做,因为它让我陷入了隐藏调用依赖关系的类中所有其他属性和方法的两难境地:如果CallBase是真的那么我必须要么
我想我想要的是:
mock.Setup(m => m.VirtualMethod()).CallBase();
所以当我打电话时mock.Object.VirtualMethod(),Moq会调用真正的实现......
问:有了Moq,有什么方法可以测试一个虚方法,当我嘲笑这个类只存在几个依赖项时?即不使用CallBase = true并且必须存根所有依赖项?
用于说明的示例代码
(使用MSTest,InternalsVisibleTo DynamicProxyGenAssembly2)
在以下示例中,TestNonVirtualMethod传递但是TestVirtualMethod失败 - 返回null.
public class Foo
{
public string NonVirtualMethod() { return GetDependencyA(); }
public virtual string VirtualMethod() { return GetDependencyA();}
internal virtual string GetDependencyA() { return "! Hit REAL Dependency A !"; }
// [... Possibly many other dependencies ...]
internal virtual …Run Code Online (Sandbox Code Playgroud) 我正在同一个类中尝试模拟内部方法。但是我的模拟失败了。
这是我的代码。
界面
public interface IStudentService
{
int GetRank(int studentId);
IList<Subject> GetSubjects(int studentId);
}
Run Code Online (Sandbox Code Playgroud)
执行
public class StudentService : IStudentService
{
private readonly IStudentRepository _studentRepository;
private readonly ISubjectRepository _subjectRepository;
public StudentService(IStudentRepository studentRepository, ISubjectRepository subjectRepository)
{
_studentRepository = studentRepository;
_subjectRepository = subjectRepository;
}
public int GetRank(int studentId)
{
IList<Subject> subjects = GetSubjects(studentId);
int rank = 0;
//
//Calculate Rank
//
return rank;
}
public virtual IList<Subject> GetSubjects(int studentId)
{
return _subjectRepository.GetAll(studentId);
}
}
Run Code Online (Sandbox Code Playgroud)
单元测试
[TestFixture]
public class StudentServiceTest
{
[SetUp]
public …Run Code Online (Sandbox Code Playgroud)