Unit Test метод, который возвращает пустоту
Требуется Unit Test метод в следующем классе
public class DeviceAuthorisationService : IDeviceAuthorisationService
{
private DeviceDetailsDTO deviceDetailsDTO = null;
private IDeviceAuthorisationRepositiory deviceAuthorisationRepositiory;
public DeviceAuthorisationService(IDeviceAuthorisationRepositioryService paramDeviceAuthorisationRepository)
{
deviceAuthorisationRepositiory = paramDeviceAuthorisationRepository;
}
public void AuthoriseDeviceProfile(long paramUserID, string paramClientMakeModel)
{
if (deviceDetailsDTO == null)
GetCellPhoneDetails(userID);
if (deviceDetailsDTO.IsDeviceSelected == false)
throw new SomeCustomExceptionA();
if (deviceDetailsDTO.CellPhoneMakeModel.ToLower() != paramClientMakeModel.ToLower())
throw new SomeCustomExceptionB;
}
public void UpdateDeviceStatusToActive(long userID)
{
if (deviceDetailsDTO == null)
throw new InvalidOperationException("UnAuthorised Device Profile Found Exception");
if (deviceDetailsDTO.PhoneStatus != (short)Status.Active.GetHashCode())
deviceAuthorisationRepositiory.UpdatePhoneStatusToActive(deviceDetailsDTO.DeviceID);
}
private void GetCellPhoneDetails(long userID)
{
deviceDetailsDTO = deviceAuthorisationRepositiory.GetSelectedPhoneDetails(userID);
if (deviceDetailsDTO == null)
throw new SomeCustomException()
}
}
Примечание:
- Имя метода = AuthoriseDeviceProfile возвращает void
- Метод проверяет userSentMakeModel на тот, который хранится в соответствии с db
- Если он совпадает - он просто возвращает (т.е. не меняет состояние)
Как мы будем использовать Unit Test этот метод?
- Издевались над Repo
- Раскрыл сценарий "ИСКЛЮЧЕНИЕ ЧЕРЕЗ"
- Вопрос в том, как Unit Test сценарий ALL WENT WELL, т.е. пользовательский makeModel, сопоставленный с репозиторием; s makeModel
Любые предложения по дизайну, чтобы сделать этот testable наиболее приветствуется
Спасибо заранее.
Ответы
Ответ 1
Так как ваш метод возвращает void, он, вероятно, имеет некоторый побочный эффект, который вы можете проверить/утвердить.
В вашем случае вариант должен состоять в том, чтобы предоставить экземпляр mock IDeviceAuthorisationRepositioryService
. Затем вы можете проверить, произошел ли вызов UpdatePhoneStatusToActive
. Вот решение, использующее Moq:
var mock = new Mock<IDeviceAuthorisationRepositioryService>();
var service = new DeviceAuthorisationService(mock.Object);
service.UpdateDeviceStatusToActive(....);
mock.Verify(x => service.UpdatePhoneStatusToActive(), Times.Never());
Ответ 2
Если метод недействителен, тогда он должен иметь некоторый наблюдаемый побочный эффект - в противном случае это бессмысленно. Поэтому вместо проверки возвращаемого значения вы проверяете побочные эффекты. В этом случае это похоже на те, которые, вероятно, связаны с исключениями в ситуациях.
(Здесь "выдает исключение" считается побочным эффектом, вы также можете думать о нем как о неявном виде возвращаемого значения, конечно...)
Ответ 3
Внедрить посмешиваемый репозиторий. Проверьте, вызваны ли определенные методы в репозитории.
Ответ 4
Вы можете установить ожидания ожидания для своих модульных тестов. В nUnit это выглядит так:
[Test]
[ExpectedException(typeof(InvalidOperationException))]
public void TestAuthoriseFail()
{
// do something that should make the tested method throw the exception
}
Ответ 5
Даже если ваш метод возвращает void, он должен делать что-то полезное для вас (в противном случае это был бы бессмысленный метод).
Из вашего кода, я предполагаю, что существуют 2 варианта "полезных" вещей, которые делает метод AuthoriseDeviceProfile
:
- вызов метода
GetSelectedPhoneDetails
на IDeviceAuthorisationRepositiory
- бросать различные исключения, основанные на определенных условиях
Поэтому для метода unit test вы должны сделать две вещи, которые соответствуют этому:
- Ввести макет
IDeviceAuthorisationRepositiory
и записать его и/или подтвердить, называется ли GetSelectedPhoneDetails
- Тестируйте методы тестирования, которые вызывают различные исключения и захватывают их, поскольку их бросают, чтобы проверить, что:
- исключение фактически брошено
- исключение, которое выбрано, является подходящим для каждого сценария