如果我模拟一个方法,我是否必须显式调用该方法来运行我的模拟实现?
我正在尝试在 Unity 项目中进行模拟。我基本上正在启动一个场景,并在 Start() 方法中执行代码。我正在尝试模拟该启动方法中发生的休息调用。
这是我的代码:
public class MyAddressablesClass
{
public virtual IEnumerator LoadRemoteCatalog()
{
// My implementation here
}
}
public class MyCode
{
public IEnumerator Start()
{
// Doing some stuff
MyAddressablesClass myAddressablesInstance = new MyAddressablesClass();
yield return myAddressablesInstance.LoadRemoteCatalog();
// Doing some other stuff
}
}
这是我的模拟实现:
private IEnumerator GetFakeCatalog() {
yield return null;
}
[UnitySetUp]
public IEnumerator Setup()
{
Mock<MyAddressablesClass> mockedClass = new Mock<MyAddressablesClass>();
mockedClass.Setup(service => service.LoadRemoteCatalog()).Returns(GetFakeCatalog());
}
[UnityTest]
public IEnumerator TestThings() {
yield return SceneManager.LoadSceneAsync("MyScene");
}
当我运行单元测试时,我不想明确地说
var mocked = new MyAddressablesClass(mockedClass.Object); yield return mocked.LoadRemoteCatalog();
以便调用 GetFakeCatalog()
。
在我的实际代码中调用
LoadRemoteCatalog()
时,它不应该自动使用我的模拟实现吗?
我想测试场景启动时发生的所有情况,所以我不想嘲笑它。
起订量并不神奇;它只会在您配置的对象上实现特定于测试的行为。
当您在被测系统 (SUT) 中编写时
MyAddressablesClass myAddressablesInstance = new MyAddressablesClass();
SUT 将使用该
MyAddressablesClass
实例,就像代码所示;不是mockedClass
。
测试创建
Mock<MyAddressablesClass>
是无关紧要的。它们是两个不同的对象。
如果您希望能够更改
MyAddressablesClass
内部 MyCode.Start
的行为,则必须以某种方式传递该对象。
根据需求,我建议使用构造函数注入或方法注入。
在这两种情况下,测试现在都能够将
mockedClass.Instance
传递给 SUT。
public class MyCode
{
private readonly MyAddressablesClass myAddressablesInstance;
public MyCode(MyAddressablesClass myAddressablesInstance)
{
this.myAddressablesInstance = myAddressablesInstance;
}
public IEnumerator Start()
{
// Doing some stuff
yield return myAddressablesInstance.LoadRemoteCatalog();
// Doing some other stuff
}
}
public class MyCode
{
public IEnumerator Start(MyAddressablesClass myAddressablesInstance)
{
// Doing some stuff
yield return myAddressablesInstance.LoadRemoteCatalog();
// Doing some other stuff
}
}