我有以下代码:
public interface Iinterface
{
Task<bool> RetrieveFromDataBase();
}
public class Class1 : Iinterface
{
public async Task<bool> RetrieveFromDataBase()
{
//do something
return true;
}
}
public class AnotherClass
{
Class1 c = new Class1();
public AnotherClass(Class1 obj)
{
c = obj;
}
public async Task<bool> ExecuteData()
{
var result = await c.RetrieveFromDataBase();
if (result)
{
//do some calculation
}
return true;
}
}
现在,我正在尝试为ExecuteData
方法编写测试用例。在此方法中,我需要绕过RetrieveFromDataBase
方法。所以我正在尝试嘲笑它。这是我编写的以下代码。
[TestClass()]
public class AnotherClassTests
{
[TestMethod()]
public async Task ExecuteDataTest()
{
Task<bool> retValue = RetrieveFromDataBaseMoq(); // this returns true
var moq = new Mock<Iinterface>();
moq.Setup(x => x.RetrieveFromDataBase()).Returns(retValue);
AnotherClass obj = new AnotherClass((Class1)moq.Object); // error thrown from here
var result = await obj.ExecuteData();
Assert.IsTrue(result);
}
}
完成的模拟成功,即不会引发任何错误。我在这里面临的问题是,当我将此模拟对象传递给构造函数一个参数时,它将引发错误System.InvalidCastException:无法将对象“ Castle.Proxies.Iinterface”转换为类型“ Class1”。
我知道它无法将模拟接口转换为具体的类类型。但是,有没有一种方法可以纠正此错误,或者无论如何将模拟对象传递给主类。
非常感谢!
答案 0 :(得分:3)
您应将变量c
声明为Iinterface
。这是使用接口的优点之一。您应该依赖于contract(interface),而不是具体的实现。之后,您就不必再依赖于具体的课程了。
public class AnotherClass
{
Iinterface c; //I removed the default new since it will get assigned in constructor
public AnotherClass(Iinterface obj)
{
c = obj;
}
public async Task<bool> ExecuteData()
{
var result = await c.RetrieveFromDataBase();
if (result)
{
//do some calculation
}
return true;
}
}
我在这里面临的问题是,类Class1还具有一些其他方法和变量,这些方法和变量未在接口中声明。
您可以在Class1内进行合成,然后将TInterface作为依赖项移到Class1内。请记住,界面是您在单元测试中会被嘲弄的
public class Class1
{
public TIinterface tinterface{get;private set;}
public Class1(TIinterface interface)
{
tinterface= interface;
}
}
public class YourCustomImplementation:TIinterface
{
public async Task<bool> RetrieveFromDataBase()
{
//do something
return true;
}
}
public class AnotherClass
{
Class1 c = new Class1();
public AnotherClass(Class1 obj)
{
c = obj;
}
public async Task<bool> ExecuteData()
{
var result = await c.tinterface.RetrieveFromDataBase();
if (result)
{
//do some calculation
}
return true;
}
}