#c# #unit-testing
#c# #модульное тестирование
Вопрос:
Пожалуйста, помогите мне с моей проблемой. У меня есть класс обслуживания, который приведен ниже:
public class RateService:IRatesService
{
...
public RatesDTO GetById(int Id)
{
return Mapper.Map<Rates, RatesDTO>(this.db.Rates.GetAll().Where(m => m.RateId == Id).First());
}
}
Интерфейс IRatesServicelooks похож на этот пример кода:
public interface IRatesService
{
.....
RatesDTO GetById(int Id);
....
}
И теперь я пытаюсь протестировать общедоступный метод RatesDTO GetById(int Id). Мой код приведен ниже:
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
Mock<IRatesService> mock = new Mock<IRatesService>();
mock.Setup(m => m.GetById(It.IsAny<int>())).Returns<RatesDTO>(total=>total);
Assert.IsNotNull(mock.Object.GetById(1));
}
}
Но когда я запускаю test, я получаю такую ошибку:
Имя теста:
TestMethod 1 Полное имя теста: Provider.Тесты.Услуги.UnitTest1.TestMethod 1Сообщение о результате:
Поставщик методов тестирования.Тесты.Услуги.UnitTest1.TestMethod 1 выдал исключение: System.ArgumentException: Невозможно преобразовать объект типа «System.Int32» к типу «Provider.BLL.DTO.RatesDTO».
Как лучше всего протестировать классы и методы обслуживания?
Комментарии:
1. Если вы пытаетесь протестировать RateService, вам следует протестировать конкретный класс, и вы не должны издеваться над ним. Mocks существует для случаев, когда вы хотите протестировать класс изолированно, поэтому вы имитируете объекты, от которых зависит класс.
Ответ №1:
Вы пытаетесь протестировать свой макет. Это не имеет никакого смысла.
Вы должны стремиться протестировать свой реальный код.В вашем случае вы можете убедиться, что ваш GetById возвращает RatesDTO с правильным значением id.
Вы могли бы использовать макет фреймворка для облегчения тестирования. например, если вы пытаетесь выполнить модульный тест и используете уровень БД, вы можете создать макет функции GetAll уровня базы данных и вернуть несколько объектов, а затем запустить тест, чтобы проверить, что вы действительно возвращаете правильный объект (тот же идентификатор).
Ответ №2:
Ваша RateService
система находится в стадии тестирования. При создании макетов для ваших модульных тестов нормой является имитация зависимостей тестируемой системы.
Итак, учитывая ваш текущий сервис, допустим, он зависит от хранилища данных.
public class RateService : IRatesService {
private readonly IDbContext db;
public RateService(IDbContext dbContext) {
this.db = dbContext;
}
//...
public RatesDTO GetById(int Id) {
return Mapper.Map<Rates, RatesDTO>(this.db.Rates.GetAll().Where(m => m.RateId == Id).First());
}
//...
}
IDbContext
будет ли зависимость от тестируемой системы.
Вы бы смоделировали это при тестировании RateService
[TestClass]
public class RateServiceUnitTests {
[TestMethod]
public void Given_ValidId_GetById_Should_Return_Dto() {
//Arrange
var validId = 1;
var fakes = new List<Rates>() {
new Rates { RateId = validId }
};
var mock = new Mock<IDbContext>();
//Assuming IDbContext.Rates.GetAll() returns an IEnumerable<Rates>
mock.Setup(m => m.Rates.GetAll()).Returns(fakes);
var sut = new RateService(mock.Object);
//Act
var result = sut.GetById(validId);
//Assert
Assert.IsNotNull(result);
}
}
Заметил, что вы также используете mapper. Вы должны убедиться, что он также настроен для теста, иначе тест завершится неудачей. При использовании статических вызовов в ваших классах они могут вызвать проблемы при попытке изолировать вашу систему для тестирования. Попробуйте также добавить mapper в качестве зависимости.