Как конвертировать в Xunit с помощью насмешек - PullRequest
0 голосов
/ 19 марта 2019

У меня есть эти два метода в моем классе обслуживания

public class PatientService : IPatientService
{
    private readonly IRestClient _restClient;
    private readonly IAppSettings _appSettings;

    public PatientService(IRestClient restClient, IAppSettings appSettings)
    {
        _restClient = restClient;
        _appSettings = appSettings;
    }

    public async Task<IList<PatientViewModel>> GetPatients(int wardId)
    {
        var url = _appSettings.Server + _appSettings.PatientServiceEndPoint + wardId;
        var token = _appSettings.Token;
        return GetPatientList(await _restClient.GetAsync<List<PatientInfo>>(url, token));
    }

    public IList<PatientViewModel> GetPatientList(IList<PatientInfo> patientInfoList)
    {
        return patientInfoList.Select(p => new PatientViewModel(p)).ToList();
    }
}

Мне нужно добавить этот код в мой Xunit.cs.Как это сделать?

Я реализовал это, и я не знаю, как продолжить.

private readonly PatientListPageViewModel _patientListPageViewModel;        
private readonly Mock<IPatientService> _patient;

public PatientServiceTests()
{
    _patient = new Mock<IPatientService>();
    _patientListPageViewModel = new PatientListPageViewModel(_patient.Object);          
}

[Fact]
public void GetListByWard_PassingWardId_GetPatientsCountAccordingToWardId()
{


}

Это то, что я пытался сделать.Как преобразовать эти два метода в сервисе для проверки?

1 Ответ

0 голосов
/ 20 марта 2019

Вы немного ошиблись.Пересматривается не проверяемый компонент , а его зависимости .При юнит-тестировании вы хотели бы тестировать юнит в изоляции.Ваш случай насмешки был бы верным, если бы вы тестировали модуль 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);
    // ...
}
...