如何在 C# 中模拟 return 虚拟数据的方法?
How to mock methods to return dummy data from them in C#?
我有一个 class,我正试图通过用 C# 编写一些单元测试来测试它。我还在单元测试中使用 Moq
库进行模拟。
下面是我的 class 中的一些方法,我想模拟这些方法,以便它们可以 return 一些我想要 return 的虚拟数据。
public class DataManager
{
public DataManager(ILoggingService loggingService, IConfiguration configuration)
{
// ...
}
// how to mock this to return dummy data?
private DataHolder GetData()
{
//... return DataHolder object
}
// how to mock this to return dummy data?
private IEnumerable<ProcessClient> GetClientValues(string value)
{
//... return IEnumerable<ProcessClient> object
}
}
这就是我测试它的方式:
private Mock<ClientUtility> utility;
[SetUp]
public void Setup()
{
utility = new Mock<ClientUtility>();
}
[Test]
public void Test1()
{
// what should I do here so that "GetData" and "GetClientValues" return dummy data when I call below class constructor?
var testName = "config1";
var testContent = "{}";
utility.Setup(x => x.Add(new DataStatus { Pin = "test" }, "data.com", "test")).Returns(Task.FromResult(true));
var dataManager = new DataManager(loggingService.Object, configuration.Object);
Assert.AreEqual(testContent, dataManager.GetStuff(testName)[0]);
}
问题:
我如何使用 Moq 或任何其他库模拟“GetData”和“GetClientValues”以从这两种方法 return 虚拟数据?这可能吗?
我认为你可以使用 CallBase = true
。
所以你的模拟将表现得像 true class.
var dataManager = new Mock<DataManager>(loggingService.Object, configuration.Object) { CallBase = true };
dataManager.Object.Method1();
dataManager.Object.Method2();
并且您可以像使用实用程序一样模拟一些方法。
在页面上按“CallBase”搜索:
https://github.com/Moq/moq4/wiki/Quickstart
更新
我制作了方法 public 来调用它们。
还有一些问题,我上次没有看到。如果你想改变它们的行为,你需要制作“虚拟”方法。
有代码示例。如您所见,GetClientValues()
returns 真实数据,因为我们使用 CallBase = true
和 GetData()
returns 虚拟数据调用默认真实实现,因为我们模拟了它的行为。
public class DataManager
{
public DataManager(ILoggingService loggingService, IConfiguration configuration)
{
// ...
}
// how to mock this to return dummy data?
public virtual DataHolder GetData()
{
return new DataHolder
{
Data = "RealData"
};
}
// how to mock this to return dummy data?
public IEnumerable<ProcessClient> GetClientValues(string value)
{
return new List<ProcessClient>
{
new ProcessClient
{
Data = "RealData"
}
};
}
}
和测试。
public class Tests
{
[SetUp]
public void Setup()
{
}
[Test]
public void Test1()
{
var loggingService = new Mock<ILoggingService>();
var config = new Mock<IConfiguration>();
var dataManager = new Mock<DataManager>(loggingService.Object, config.Object){CallBase = true};
dataManager.Setup(x => x.GetData()).Returns(new DataHolder { Data = "FakeData" });
Assert.AreEqual("RealData", dataManager.Object.GetClientValues("test").First().Data);
Assert.AreEqual("FakeData", dataManager.Object.GetData().Data);
}
}
但无论如何我认为,这种方法不适合测试。
测试私有方法有问题。我们有一些方法(例如Invoke()
),但总的来说,“如果你想对私有方法进行单元测试,可能会出现问题”。我想推荐你阅读一些关于测试设计和编写可测试代码的内容。
关于测试私有方法 How do you unit test private methods?.
我有一个 class,我正试图通过用 C# 编写一些单元测试来测试它。我还在单元测试中使用 Moq
库进行模拟。
下面是我的 class 中的一些方法,我想模拟这些方法,以便它们可以 return 一些我想要 return 的虚拟数据。
public class DataManager
{
public DataManager(ILoggingService loggingService, IConfiguration configuration)
{
// ...
}
// how to mock this to return dummy data?
private DataHolder GetData()
{
//... return DataHolder object
}
// how to mock this to return dummy data?
private IEnumerable<ProcessClient> GetClientValues(string value)
{
//... return IEnumerable<ProcessClient> object
}
}
这就是我测试它的方式:
private Mock<ClientUtility> utility;
[SetUp]
public void Setup()
{
utility = new Mock<ClientUtility>();
}
[Test]
public void Test1()
{
// what should I do here so that "GetData" and "GetClientValues" return dummy data when I call below class constructor?
var testName = "config1";
var testContent = "{}";
utility.Setup(x => x.Add(new DataStatus { Pin = "test" }, "data.com", "test")).Returns(Task.FromResult(true));
var dataManager = new DataManager(loggingService.Object, configuration.Object);
Assert.AreEqual(testContent, dataManager.GetStuff(testName)[0]);
}
问题:
我如何使用 Moq 或任何其他库模拟“GetData”和“GetClientValues”以从这两种方法 return 虚拟数据?这可能吗?
我认为你可以使用 CallBase = true
。
所以你的模拟将表现得像 true class.
var dataManager = new Mock<DataManager>(loggingService.Object, configuration.Object) { CallBase = true };
dataManager.Object.Method1();
dataManager.Object.Method2();
并且您可以像使用实用程序一样模拟一些方法。
在页面上按“CallBase”搜索:
https://github.com/Moq/moq4/wiki/Quickstart
更新 我制作了方法 public 来调用它们。 还有一些问题,我上次没有看到。如果你想改变它们的行为,你需要制作“虚拟”方法。
有代码示例。如您所见,GetClientValues()
returns 真实数据,因为我们使用 CallBase = true
和 GetData()
returns 虚拟数据调用默认真实实现,因为我们模拟了它的行为。
public class DataManager
{
public DataManager(ILoggingService loggingService, IConfiguration configuration)
{
// ...
}
// how to mock this to return dummy data?
public virtual DataHolder GetData()
{
return new DataHolder
{
Data = "RealData"
};
}
// how to mock this to return dummy data?
public IEnumerable<ProcessClient> GetClientValues(string value)
{
return new List<ProcessClient>
{
new ProcessClient
{
Data = "RealData"
}
};
}
}
和测试。
public class Tests
{
[SetUp]
public void Setup()
{
}
[Test]
public void Test1()
{
var loggingService = new Mock<ILoggingService>();
var config = new Mock<IConfiguration>();
var dataManager = new Mock<DataManager>(loggingService.Object, config.Object){CallBase = true};
dataManager.Setup(x => x.GetData()).Returns(new DataHolder { Data = "FakeData" });
Assert.AreEqual("RealData", dataManager.Object.GetClientValues("test").First().Data);
Assert.AreEqual("FakeData", dataManager.Object.GetData().Data);
}
}
但无论如何我认为,这种方法不适合测试。
测试私有方法有问题。我们有一些方法(例如Invoke()
),但总的来说,“如果你想对私有方法进行单元测试,可能会出现问题”。我想推荐你阅读一些关于测试设计和编写可测试代码的内容。
关于测试私有方法 How do you unit test private methods?.