Вы немного ошиблись.Пересматривается не проверяемый компонент , а его зависимости .При юнит-тестировании вы хотели бы тестировать юнит в изоляции.Ваш случай насмешки был бы верным, если бы вы тестировали модуль PatientListPageViewModel
, но поскольку ваш тестовый класс называется PatientServiceTests
, я предполагаю, что вы действительно хотели протестировать PatientService
.Если бы вы хотели проверить первое, вы были бы совершенно правы, если бы имитировали IPatientService
, но при тестировании PatientService
, IRestClient
и IAppSettings
должны быть смоделированы
public PatientServiceTests()
{
_restClientMock = new Mock<IRestClient>();
_appSettingsMock = new Mock<IAppSettings>();
_patientService = new PatientService(_restClientMock.Object, _appSettingsMock.Object);
}
И ваш тест может бытьчто-то вроде
[Fact]
public async Task ReturnsCorrectPatientList() // async supported as of xUnit 1.9
{
// set up the mock
_restClientMock.SetUp(restClient => restClient.GetAsync<List<Patient>>(It.IsAny<string>(), It.IsAny<string>())
.Returns(() => Task.FromResult(/* what patients it shall return */));
var result = await _patientService.GetPatients(0);
// compare whether the returned result matches your expectations
}
Если вы хотите проверить, правильно ли сформирован URL, вы можете использовать Verify
[Theory]
[InlineData("SERVER", "ENDPOINT", 12, "1234", "SERVERENDPOINT12")]
[InlineData("https://localhost:65000", "/patients/", 5, https://localhost:65000/patients/5")]
public void TestWhetherCorrectUrlIsCalled(string server, string endpoint, int wardId, string token, string expectedUrl)
{
_appSettingsMock.SetupGet(appSettings => appSettings.Server).Returns(server);
_appSettingsMock.SetupGet(appSettings => appSettings.PatientServiceEndPoint).Returns(endpoint);
_appSettingsMock.SetupGet(appSettings => appSettings.Token).Returns(token);
_restClientMock.SetUp(restClient => restClient.GetAsync<List<Patient>>(It.IsAny<string>(), It.IsAny<string>())
.Returns(() => Task.FromResult(new List<Patient>()));
// we do not need the result
await _patientService.GetPatients(wardId);
_restClientMock.Verify(restClient => restClient.GetAsync<List<Patient>>(exptectedUrl, token), Times.Once);
}
В этом случае мы настраиваем IRestClient
,так как это вернуло бы null
в противном случае.И await null
приведет к провалу вашего теста.После вызова GetPatients
мы используем Verify
, чтобы убедиться, что GetAsync
был вызван с правильными параметрами.Если он не был вызван, Verify
сгенерирует и ваш тест не пройдёт.Times.Once
означает, что GetAsync
должен вызываться один раз и только один раз.
На примечании стороны : Viewmodels должны иметь значение только в контексте вашего пользовательского интерфейса.Сервисы должны быть независимыми и, следовательно, возвращать не модели представления, как вы, а POCO (или, возможно, модели домена).В этом случае интерфейс вашего сервиса должен быть
public interface IPatientService
{
public async Task<IList<Patient>> GetPatients(int wardId);
// ...
}