#c# #inheritance #methods #moq
#c# #наследование #методы #moq
Вопрос:
У меня есть несколько методов веб-API, для которых я хочу написать модульные тесты. Им нужен доступ к базе данных, поэтому, естественно, я хотел уточнить эту часть.
Доступ к классам хранилища осуществляется через интерфейс, и класс, реализующий метод API, наследует интерфейс. Чего я не знаю, так это как издеваться над унаследованным интерфейсом в модульном тестировании.
public class CreateWishList : APIAccess
{
public long CreateWishListV1(long userId, string wishListName)
{
// Do stuff like
long result = Storage.CreateWishList(userId, wishListName);
return resu<
}
}
public class APIAccess
{
protected IStorage Storage { get; private set; }
public APIAccess() : this(new APIStorage()) { }
public APIAccess(IStorage storage)
{
Storage = storage;
}
}
public interface IStorage
{
long CreateWishList(long userId, string wishListName);
}
Итак, я хочу провести модульное тестирование CreateWishListV1(...)
метода, и чтобы сделать это без доступа к базе данных, мне нужно смоделировать то, что Storage.CreateWishList(...)
возвращает. Как мне это сделать?
Обновить:
Я пытаюсь что-то вроде этого:
[Test]
public void CreateWishListTest()
{
var mockAccess = new Mock<APIAccess>(MockBehavior.Strict);
mockAccess.Setup(m => m.Device.CreateWishList(It.IsAny<long>(), It.IsAny<string>())).Returns(123);
var method = new CreateWishList();
method.Storage = mockAccess.Object;
long response = method.CreateWishListV1(12345, "test");
Assert.IsTrue(response == 123, "WishList wasn't created.");
}
Также пришлось изменить Storage
свойство APIAccess
на public.
Комментарии:
1. Что именно вы пытаетесь протестировать? Почему вы вызываете CreateWishListV1 в макете? Я думаю, что это метод, который вы хотите протестировать?
2. Да, я делал это неправильно. Обновил вопрос; это лучше?
Ответ №1:
У меня в голове не укладывается:
var storage = new Mock<IStorage>();
storage.Setup(x => x.CreateWishList(It.IsAny<long>(), It.IsAny<string>())
.Returns(10);
Затем создайте свой CreateWishList
объект с его собственным конструктором, принимающим IStorage
.
var createWishList = new CreateWishList(storage.Object);
Для модульного тестирования вашего CreateWishList()
метода вам следует написать отдельный тест. Этот тест должен проводиться исключительно для проверки кода в CreateWishListV1()
.
Комментарии:
1. Есть ли способ сделать это без создания конструктора?
2. Вы могли бы сделать
Storage
свойство общедоступным, чтобы модульный тест мог его установить. В любом случае — вы не можете ожидать, что модульный тест назначит зависимость, когда вы создаете экземпляр зависимости внутри объекта.3. Да, вы могли бы внедрить хранилище с помощью свойства или задать его с помощью отражения. Но создание конструктора, который принимает хранилище, было бы самым чистым способом, ИМХО.