Подтвердить что ты не робот

Мок с заданием ждут

Поскольку я преобразовал свои методы WCF в Async, мои модульные тесты потерпели неудачу, и я не могу понять правильный синтаксис, чтобы заставить их работать.

Класс прокси-сервера Cllient

 public interface IClientProxy
{
     Task DoSomething(CredentialDataList credentialData, string store);
}

класс обслуживания

  public class CredentialSync : ICredentialSync
{
    private ICredentialRepository _repository;

    private IClientProxy _client;

    public CredentialSync()
    {
        this._repository = new CredentialRepository();
        this._client = new ClientProxy();
    }

    public CredentialSync(ICredentialRepository repository, IClientProxy client)
    {
        this._repository = repository;
        this._client = client;
    }

   public async Task Synchronise(string payrollNumber)
    {
        try
        {
            if (string.IsNullOrEmpty(payrollNumber))
            {
                .... some code
              }
            else
            {
                CredentialDataList credentialData = new CredentialDataList();
                List<CredentialData> credentialList = new List<CredentialData>();

                // fetch the record from the database
                List<GetCredentialData_Result> data = this._repository.GetCredentialData(payrollNumber);
                var pinData = this._repository.GetCredentialPinData(payrollNumber);

                // get the stores for this employee
                var storeList = data.Where(a => a.StoreNumber != null)
                    .GroupBy(a => a.StoreNumber)
                    .Select(x => new Store { StoreNumber = x.Key.ToString() }).ToArray();

                var credential = this.ExtractCredentialData(data, pinData, payrollNumber);

                credentialList.Add(credential);
                credentialData.CredentialList = credentialList;

                foreach (var store in storeList)
                {       
                  //this line causes an Object reference not set to an instance of an object error
                   await  _client.DoSomething(credentialData, store.StoreNumber);

                }
            }
        }
        catch (Exception ex)
        {
            throw new FaultException<Exception>(ex);
        }
    }

Класс тестирования

 /// </summary>
[TestClass]
public class SynchTest
{

    private Mock<ICredentialRepository> _mockRepository;
    private Mock<IClientProxy> _mockService;

    [TestInitialize]
    public void Setup()
    {
       ... some setups for repository which work fine
    }

[TestMethod]      
    public async Task SynchroniseData_WithOneEmployee_CallsReplicateService()
    {
        this._mockService = new Mock<IClientProxy>();
        this._mockService.Setup(x=>x.DoSomething(It.IsAny<CredentialDataList>(), It.IsAny<string>()));
        // arrange
        string payrollNumber = "1";
        CredentialSync service = new CredentialSync(this._mockRepository.Object, this._mockService.Object);

        // act
        await service.Synchronise(payrollNumber);

        // assert                 
        this._mockService.VerifyAll();
    }

Ошибка при вызове ClientProxy.DoSomething:

Ссылка на объект не установлена ​​в экземпляр объекта

Параметры оба хороши.

Если я конвертирую свой метод ClientProxy.DoSomething в синхронный метод (public void DoSomething(...)) код работает нормально, но мне нужно, чтобы это называлось асинхронно

4b9b3361

Ответ 1

DoSomething возвращает null вместо возврата Task, и вы получаете исключение при его ожидании. Вы должны указать при построении макета, что он должен вернуть Task.

В этом случае кажется, что вы можете просто вернуть уже выполненную задачу, используя Task.FromResult поэтому настройка макета должна выглядеть следующим образом:

this._mockService.Setup(...).Returns(Task.FromResult(false));

Начиная со следующей версии .Net(4.6) вы можете использовать Task.CompletedTask следующим образом:

this._mockService.Setup(...).Returns(Task.CompletedTask);

Ответ 2

Вы можете уменьшить количество помех в коде, используя ReturnsAsync

this._mockService.Setup(...).ReturnsAsync(false);

Таким образом вы можете удалить часть Task.FromResult кода

Ответ 3

Я думаю, что вам нужно вернуть Task из макета DoSomething

this._mockService.Setup(x => x.DoSomething(It.IsAny<CredentialDataList>(), It.IsAny<string>()))
    .Returns(Task.FromResult<int>(0));