具有 Moq 单元测试的 Net Framework Xunit 保持调用原始功能
Net Framework Xunit With Moq Unit Testing Keep Calling The Original Function
我在模拟时遇到问题,因为它一直调用原始函数。这是我的演示代码
第一个文件是包含我要模拟的函数的接口。
public interface IDemoReplace
{
int FunctionToBeReplaced();
}
第二个文件是一个 class,它实际上具有函数
的实现
public class DemoReplace : IDemoReplace
{
public int FunctionToBeReplaced()
{
//this function contains sql query in my real project
return 1;
}
}
第三个文件是我要测试的class
public class ClassToBeTested
{
public int TestThisFunction()
{
IDemoReplace replace = new DemoReplace();
var temp = replace.FunctionToBeReplaced();
return temp;
}
}
最后一个文件是测试class
public class TestClass
{
[Fact]
public void TryTest()
{
using (var mock = AutoMock.GetLoose()) {
//Arrange
mock.Mock<IDemoReplace>()
.Setup(x => x.FunctionToBeReplaced())
.Returns(returnTwo());
var classToBeTested = mock.Create<ClassToBeTested>();
var expected = 2;
//Act
var actual = classToBeTested.TestThisFunction();
//Assert
Assert.Equal(expected, actual);
}
}
public int returnTwo() {
return 2;
}
}
此测试将失败,预期为 2,实际为 1。当我尝试调试时,它不会调用 returnTwo
,而是调用原始函数。
我是单元测试的新手,所以我错过了什么?请注意,上面的代码只是我实际项目中发生的事情的演示。 FunctionToBeReplaced
实际上是一个从数据库执行和 return 记录的函数,所以我想模拟该函数。
谢谢:)
这是一个设计问题。被测主题与实现问题紧密耦合,这使得很难隔离主题以便对其进行单元测试。
它(主题)正在手动创建它的依赖关系
IDemoReplace replace = new DemoReplace();
理想情况下,您希望显式注入依赖项。这些依赖关系也应该是抽象的,而不是具体的。
public class ClassToBeTested {
private readonly IDemoReplace dependency;
public ClassToBeTested(IDemoReplace dependency) {
this.dependency = dependency;
}
public int TestThisFunction() { ;
var temp = dependency.FunctionToBeReplaced();
return temp;
}
}
在 运行 时,可以完全或通过容器注入实现(或模拟)。
显示的原始示例中的测试现在应该按预期运行。
public class TestClass {
[Fact]
public void TryTest() {
using (var mock = AutoMock.GetLoose()) {
//Arrange
var expected = returnTwo();
mock.Mock<IDemoReplace>()
.Setup(x => x.FunctionToBeReplaced())
.Returns(expected);
var classToBeTested = mock.Create<ClassToBeTested>();
//Act
var actual = classToBeTested.TestThisFunction();
//Assert
Assert.Equal(expected, actual);
}
}
public int returnTwo() {
return 2;
}
}
我在模拟时遇到问题,因为它一直调用原始函数。这是我的演示代码
第一个文件是包含我要模拟的函数的接口。
public interface IDemoReplace
{
int FunctionToBeReplaced();
}
第二个文件是一个 class,它实际上具有函数
的实现public class DemoReplace : IDemoReplace
{
public int FunctionToBeReplaced()
{
//this function contains sql query in my real project
return 1;
}
}
第三个文件是我要测试的class
public class ClassToBeTested
{
public int TestThisFunction()
{
IDemoReplace replace = new DemoReplace();
var temp = replace.FunctionToBeReplaced();
return temp;
}
}
最后一个文件是测试class
public class TestClass
{
[Fact]
public void TryTest()
{
using (var mock = AutoMock.GetLoose()) {
//Arrange
mock.Mock<IDemoReplace>()
.Setup(x => x.FunctionToBeReplaced())
.Returns(returnTwo());
var classToBeTested = mock.Create<ClassToBeTested>();
var expected = 2;
//Act
var actual = classToBeTested.TestThisFunction();
//Assert
Assert.Equal(expected, actual);
}
}
public int returnTwo() {
return 2;
}
}
此测试将失败,预期为 2,实际为 1。当我尝试调试时,它不会调用 returnTwo
,而是调用原始函数。
我是单元测试的新手,所以我错过了什么?请注意,上面的代码只是我实际项目中发生的事情的演示。 FunctionToBeReplaced
实际上是一个从数据库执行和 return 记录的函数,所以我想模拟该函数。
谢谢:)
这是一个设计问题。被测主题与实现问题紧密耦合,这使得很难隔离主题以便对其进行单元测试。
它(主题)正在手动创建它的依赖关系
IDemoReplace replace = new DemoReplace();
理想情况下,您希望显式注入依赖项。这些依赖关系也应该是抽象的,而不是具体的。
public class ClassToBeTested {
private readonly IDemoReplace dependency;
public ClassToBeTested(IDemoReplace dependency) {
this.dependency = dependency;
}
public int TestThisFunction() { ;
var temp = dependency.FunctionToBeReplaced();
return temp;
}
}
在 运行 时,可以完全或通过容器注入实现(或模拟)。
显示的原始示例中的测试现在应该按预期运行。
public class TestClass {
[Fact]
public void TryTest() {
using (var mock = AutoMock.GetLoose()) {
//Arrange
var expected = returnTwo();
mock.Mock<IDemoReplace>()
.Setup(x => x.FunctionToBeReplaced())
.Returns(expected);
var classToBeTested = mock.Create<ClassToBeTested>();
//Act
var actual = classToBeTested.TestThisFunction();
//Assert
Assert.Equal(expected, actual);
}
}
public int returnTwo() {
return 2;
}
}