#c# #nunit #moq
#c# #nunit #moq
Вопрос:
У меня есть следующий фрагмент кода. Хотя настройка с retrurn true, но значение всегда возвращает false.
Может кто-нибудь посоветовать, как получить значение как true?
public interface IDatabaseService
{
bool ProcessSQL(INApplicationProcessDTO inApplicationProcessDTO, string connectionString, string storedProcedureName);
bool CompleteRun(INApplicationProcessDTO inApplicationProcessDTO, string connectionString, string storedProcedureName);
}
—-КЛАСС———-
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);
}
Ценю вашу помощь.
Ответ №1:
Есть пара небольших проблем с вашим тестовым кодом.
Сначала позвольте мне показать, как вы должны это реализовать, а затем позвольте мне дать вам некоторые объяснения:
[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);
}
- Во-первых, я бы предложил использовать несколько более осмысленные имена для ваших тестов. Здесь я использовал заданную структуру When Then, чтобы описать, при каких обстоятельствах (учитывая), если запускается определенное действие (когда), чего я ожидаю (тогда)
- Я также предлагаю использовать
Arrange
Act
Assert
комментарии и , чтобы визуально разделить различные этапы вашего тестового примера - Вызовы
Setup
методов обычно не зависят от конкретных объектов. Причина этого заключается в том, что классы сравниваются по ссылке. Таким образом, даже если у вас есть два, казалось бы, идентичных экземпляра (например:iNApplicationProcessDTOTest
иiNApplicationProcessDTO
), они разные. Вот почему фиктивная функция не вызывается.- Используйте
It.IsAny<T>()
вызовы вSetup
фазе и используйте конкретные значения вVerify
фазе.
- Используйте
- Если один из методов издеваемого объекта не вызывается SUT (тестируемой системой), то вам это не нужно
Setup
.- Но вы все равно можете убедиться, что он не был вызван (
Verify(..., Times.Never);
)
- Но вы все равно можете убедиться, что он не был вызван (
Комментарии:
1. Большое спасибо за ваш ответ. Вы помогли мне больше понять о макете и модульном тестировании. Я новичок в модульном тестировании. Ваш ответ решил мою проблему.