Я пытался написать несколько тестов в NUnit для моих общих методов, но безуспешно. Я надеюсь, что смогу прояснить ситуацию, так как мне пришлось перефразировать мой код.
DoBusinessLogic () - это метод, который я хочу проверить. Он вызывает два других метода из базового класса:
public class MySvc : BaseSvc, IMySvc
{
private readonly IMyRepo _repo;
private readonly IMyConnectorClass _connector
public MySvc(IMyRepo repo) : base(repo)
{
_repo = repo;
_connector = _repo.GetConnector();
}
public async Task DoBusinessLogic(int id1, int id2){
bool doesFirstObjectExist = await CheckMainObjExists<Foo>(id1, _connector);
await CheckSubObjExists<Bar>(id2, _connector);
// further business logic
}
}
Эти методы, в свою очередь, вызывают один и тот же метод репозитория, но имеют разную логику:
public abstract class BaseSvc : IBaseSvc
{
private readonly IBaseRepo _repo
protected BaseSvc(IBaseRepo repo)
{
_repo = repo;
}
protected async Task<bool> CheckMainObjExists<T>(int? id, IMyConnectorClass connector)
{
return await _repo.GetObjectByIdAsync<T>(Id, connector) != null;
}
protected async Task CheckSubObjExists<T>(int? id, IMyConnectorClass connector)
{
if (await _repo.GetObjectByIdAsync<T>(Id, connector) == null)
{ throw new Exception("Object not found!"); }
}
}
Далее я хочу написать unit-тест для DoBusinessLogic () в классе MySvc. К сожалению, похоже, я не могу высмеять ответы из хранилища.
[TestFixture]
public class MySvcTests
{
private MySvc _svc;
private Mock<IMyRepo> _repoMock;
private Mock<IMyConnectorClass> _connectorMock;
[SetUp]
public void SetUp()
{
_repoMock = new Mock<IMyRepo>() {};
_connectorMock = new Mock<IMyConnectorClass>();
_repo.SetUp(r => r.GetConnector()).Return(_connectorMock.Object);
_svc = new MySvc(_repoMock);
}
/*
My intent in this test, is to make CheckMainObjExists() pass,
but make CheckSubObjExist() fail.
*/
[Test]
public async Task DoBusinessLogic_If2ndObjectNotExist_ThrowException()
{
// This should return an object
_repoMock.Setup(r => r.GetObjectByIdAsync<Foo>(It.IsAny<int>(), _connectorMock.Object))
.ReturnsAsync(new Foo());
// This should return null
_repoMock.Setup(r => r.GetObjectByIdAsync<Bar>(It.IsAny<int>(), _connectorMock.Object))
.ReturnsAsync((Bar) null);
Assert.Throws<Exception>(await _svc.DoBusinessLogic());
}
}
Однако, когда я запускаю тест, оба метода, которые я настроил для своего фиктивного репо, возвращают ноль, в то время как я ожидаю "true" от первого.
Я не знаю, где находится проблема, но у меня есть подозрения:
- Можно ли настроить метод, используя в качестве параметра макет объекта? В этом случае возможно ли использовать _connectorMock.Object в качестве параметра настройки?
- Можно ли настроить один и тот же универсальный метод несколько раз, но каждый раз для другого типа? Сначала это настройка для Foo, затем для Bar.