模拟 - 虽然设置 .Returns(true) 但总是得到 false
Mock - Although setup .Returns(true) but always get false
我有如下代码片段。虽然设置为 retrurn true 但值始终 return false.
有人可以建议如何将值检索为 true 吗?
public interface IDatabaseService
{
bool ProcessSQL(INApplicationProcessDTO inApplicationProcessDTO, string connectionString, string storedProcedureName);
bool CompleteRun(INApplicationProcessDTO inApplicationProcessDTO, string connectionString, string storedProcedureName);
}
----CLASS------------
public static class INHelper
{
public static bool CompleteRun(INApplicationProcessDTO inApplicationProcessDTO, string connectionString = null, IDatabaseService databaseService = null)
{
if (inApplicationProcessDTO == null)
{
return false;
}
if (inApplicationProcessDTO.Data == null)
{
return false;
}
const string storedProcedureName = "PSP_PWS_INApplication_Application_Process_CompleteRun";
// Get Connection String to Parity4 Database from Parity4 WebService Web.config
if (connectionString == null)
{
if (ConfigurationManager.ConnectionStrings["ConnectionString"] != null)
{
connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
}
}
if (string.IsNullOrWhiteSpace(connectionString))
{
return false;
}
if (databaseService == null)
{
databaseService = new DatabaseService();
}
//Why always return false line below
return databaseService.CompleteRun(inApplicationProcessDTO, connectionString, storedProcedureName);
}
}
----测试方法----
public void When_CompleteRun_ConnectionValid_Expect_True()
{
var iNApplicationProcessDTOTest = new INApplicationProcessDTO()
{
Data = new System.Xml.Linq.XDocument(),
ErrorCount = 0,
Errors = ""
};
Mock<IDatabaseService> iDatabaseService = null;
iDatabaseService = new Mock<IDatabaseService>();
iDatabaseService.Setup(t => t.CompleteRun(iNApplicationProcessDTOTest, "test", "test")).Returns(true);
iDatabaseService.Setup(t => t.ProcessSQL(iNApplicationProcessDTOTest, "test", "test")).Returns(true);
var iNApplicationProcessDTO = new INApplicationProcessDTO()
{
Data = new System.Xml.Linq.XDocument(),
ErrorCount = 0,
Errors = ""
};
var actual = INHelper.CompleteRun(iNApplicationProcessDTO, "a", iDatabaseService.Object);
//actual always false although Returns(true) in Setup
Assert.AreEqual(true, actual);
}
感谢您的帮助。
您的测试代码有几个小问题。
首先让我展示你应该如何实现它,然后让我给你一些解释:
[Fact]
public void GivenAFlawlessDatabaseService_WhenICallCompleteRun_ThenItCallsTheUnderlyingServicesCompleteRun()
{
//Arrange
const string connectionString = "a";
var iDatabaseService = new Mock<IDatabaseService>();
iDatabaseService
.Setup(db => db.CompleteRun(It.IsAny<INApplicationProcessDTO>(), It.IsAny<string>(), It.IsAny<string>()))
.Returns(true);
var iNApplicationProcessDTO = new INApplicationProcessDTO
{
Data = new XDocument(),
ErrorCount = 0,
Errors = ""
};
//Act
var actual = INHelper.CompleteRun(iNApplicationProcessDTO, connectionString, iDatabaseService.Object);
//Assert
Assert.True(actual);
iDatabaseService.Verify(db => db.CompleteRun(iNApplicationProcessDTO, connectionString, "PSP_PWS_INApplication_Application_Process_CompleteRun"), Times.Once);
iDatabaseService.Verify(db => db.ProcessSQL(It.IsAny<INApplicationProcessDTO>(), It.IsAny<string>(), It.IsAny<string>()), Times.Never);
}
- 首先,我建议为您的测试使用更有意义的名称。在这里,我使用了一个 Given When Then 结构来描述在什么情况下(给定)如果触发特定操作(何时)我会期望什么(然后)
- 我还建议使用
Arrange
、Act
和 Assert
注释来直观地分隔测试用例的不同阶段
Setup
方法调用通常不依赖具体对象。其背后的原因是 类 是通过引用进行比较的。因此,即使您有两个看似相同的实例(例如:iNApplicationProcessDTOTest
和 iNApplicationProcessDTO
),它们也是不同的。这就是为什么不调用模拟函数的原因。
- 在
Setup
阶段使用It.IsAny<T>()
调用,在Verify
阶段使用具体值。
- 如果模拟对象的方法之一未被 SUT(被测系统)调用,则您不需要
Setup
它。
- 但是你仍然可以验证它没有被调用(
Verify(..., Times.Never);
)
我有如下代码片段。虽然设置为 retrurn true 但值始终 return false.
有人可以建议如何将值检索为 true 吗?
public interface IDatabaseService
{
bool ProcessSQL(INApplicationProcessDTO inApplicationProcessDTO, string connectionString, string storedProcedureName);
bool CompleteRun(INApplicationProcessDTO inApplicationProcessDTO, string connectionString, string storedProcedureName);
}
----CLASS------------
public static class INHelper
{
public static bool CompleteRun(INApplicationProcessDTO inApplicationProcessDTO, string connectionString = null, IDatabaseService databaseService = null)
{
if (inApplicationProcessDTO == null)
{
return false;
}
if (inApplicationProcessDTO.Data == null)
{
return false;
}
const string storedProcedureName = "PSP_PWS_INApplication_Application_Process_CompleteRun";
// Get Connection String to Parity4 Database from Parity4 WebService Web.config
if (connectionString == null)
{
if (ConfigurationManager.ConnectionStrings["ConnectionString"] != null)
{
connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
}
}
if (string.IsNullOrWhiteSpace(connectionString))
{
return false;
}
if (databaseService == null)
{
databaseService = new DatabaseService();
}
//Why always return false line below
return databaseService.CompleteRun(inApplicationProcessDTO, connectionString, storedProcedureName);
}
}
----测试方法----
public void When_CompleteRun_ConnectionValid_Expect_True()
{
var iNApplicationProcessDTOTest = new INApplicationProcessDTO()
{
Data = new System.Xml.Linq.XDocument(),
ErrorCount = 0,
Errors = ""
};
Mock<IDatabaseService> iDatabaseService = null;
iDatabaseService = new Mock<IDatabaseService>();
iDatabaseService.Setup(t => t.CompleteRun(iNApplicationProcessDTOTest, "test", "test")).Returns(true);
iDatabaseService.Setup(t => t.ProcessSQL(iNApplicationProcessDTOTest, "test", "test")).Returns(true);
var iNApplicationProcessDTO = new INApplicationProcessDTO()
{
Data = new System.Xml.Linq.XDocument(),
ErrorCount = 0,
Errors = ""
};
var actual = INHelper.CompleteRun(iNApplicationProcessDTO, "a", iDatabaseService.Object);
//actual always false although Returns(true) in Setup
Assert.AreEqual(true, actual);
}
感谢您的帮助。
您的测试代码有几个小问题。
首先让我展示你应该如何实现它,然后让我给你一些解释:
[Fact]
public void GivenAFlawlessDatabaseService_WhenICallCompleteRun_ThenItCallsTheUnderlyingServicesCompleteRun()
{
//Arrange
const string connectionString = "a";
var iDatabaseService = new Mock<IDatabaseService>();
iDatabaseService
.Setup(db => db.CompleteRun(It.IsAny<INApplicationProcessDTO>(), It.IsAny<string>(), It.IsAny<string>()))
.Returns(true);
var iNApplicationProcessDTO = new INApplicationProcessDTO
{
Data = new XDocument(),
ErrorCount = 0,
Errors = ""
};
//Act
var actual = INHelper.CompleteRun(iNApplicationProcessDTO, connectionString, iDatabaseService.Object);
//Assert
Assert.True(actual);
iDatabaseService.Verify(db => db.CompleteRun(iNApplicationProcessDTO, connectionString, "PSP_PWS_INApplication_Application_Process_CompleteRun"), Times.Once);
iDatabaseService.Verify(db => db.ProcessSQL(It.IsAny<INApplicationProcessDTO>(), It.IsAny<string>(), It.IsAny<string>()), Times.Never);
}
- 首先,我建议为您的测试使用更有意义的名称。在这里,我使用了一个 Given When Then 结构来描述在什么情况下(给定)如果触发特定操作(何时)我会期望什么(然后)
- 我还建议使用
Arrange
、Act
和Assert
注释来直观地分隔测试用例的不同阶段 Setup
方法调用通常不依赖具体对象。其背后的原因是 类 是通过引用进行比较的。因此,即使您有两个看似相同的实例(例如:iNApplicationProcessDTOTest
和iNApplicationProcessDTO
),它们也是不同的。这就是为什么不调用模拟函数的原因。- 在
Setup
阶段使用It.IsAny<T>()
调用,在Verify
阶段使用具体值。
- 在
- 如果模拟对象的方法之一未被 SUT(被测系统)调用,则您不需要
Setup
它。- 但是你仍然可以验证它没有被调用(
Verify(..., Times.Never);
)
- 但是你仍然可以验证它没有被调用(