Soru NSubstitute - async için alındı ​​- "çağrı beklemez" uyarısı


Eşzamanlı bir yöntemin doğru parametrelerle çağrıldığını doğrulamaya çalışıyorum. Ancak uyarıyı aldım:

"Bu çağrı beklemediğinden, mevcut yöntemin yürütülmesi çağrının tamamlanmasından önce devam ediyor." Bekleme "operatörünü aramanın sonucuna uygulamayı düşünün". Bu uyarı, altındaki kod satırında görünür. //Assert yorum (aşağıda).

Kullanarak benim test NSubstitute Şöyleki:

[Test]
public async Task SimpleTests()
{
  //Arrange
  var request = CreateUpdateItemRequest();

  databaseHelperSub.ExecuteProcAsync(Arg.Any<DatabaseParams>()).Returns(Task.FromResult((object)null));

  //Act      
  await underTest.ExecuteAsync(request);

  //Assert
  databaseHelperSub.Received().ExecuteProcAsync(Arg.Is<DatabaseParams>(
    p => p.StoredProcName == StoredProcedureName
         && p.Parameters[0].ParameterName == "Param1"
         && p.Parameters[0].Value.ToString() == "Value1"
         && p.Parameters[1].ParameterName == "Param2"
         && p.Parameters[1].Value.ToString() == "Value2"));
}

Test yöntemi altında birim underTest.ExecuteAsync(request) aramalar ExecuteProcedureAsync ve bekler:

var ds = await DatabaseHelper.ExecuteProcAsync(dbParams);

NSubstitute ile test edilen birimin çalıştırılmasından sonra Received () yapılması gerektiği gerçeğinden dolayı. RhinoMocks’ta ise beklemek Test edilen ünite gerçekleşmeden önce bir çağrının gerçekleşmesi için. RhinoMocks, Task.FromResult () öğesini döndürürken, NSubstitute bunu yapamaz.

Çalıştığı RhinoMocks eşdeğeri şudur:

[Test]
        public async Task SimpleTest()
        {
            // Arrange
            var request = new UpdateItemRequest();

            databaseHelperMock.Expect(m => m.ExecuteProcAsync(Arg<DatabaseParams>.Matches(
                p =>   p.StoredProcName == StoredProcedureName
                    && p.Parameters[0].ParameterName == "Param1"
                    && p.Parameters[0].Value.ToString() == "Value1"
                    && p.Parameters[1].ParameterName == "Param2"
                    && p.Parameters[1].Value.ToString() == "Value2
                ))).Return(Task.FromResult<object>(null));

            // Act
            await underTest.ExecuteAsync(request);

        }

Sorunu kaldırmak için bir uzantı yöntemi ekleyebileceğiniz bir geçici çözüm olduğunu gördüm:

  public static class TestHelper
  {
    public static void IgnoreAwait(this Task task)
    {

    }
  }

Benim test hattım anlamında NSubstitute aşağıdaki gibi çalıştırılabilir ve uyarı gider:

databaseHelperSub.Received().ExecuteProcAsync(Arg.Is<DatabaseParams>(
        p => p.StoredProcName == StoredProcedureName
             && p.Parameters[0].ParameterName == "Param1"
             && p.Parameters[0].Value.ToString() == "Value1"
             && p.Parameters[1].ParameterName == "Param2"
             && p.Parameters[1].Value.ToString() == "Value2")).IgnoreAwait();
    }

Ancak, bunun için daha iyi bir çözüm olması gerektiğini düşündüm?


18
2017-07-09 13:14


Menşei


Bu bir derleyici ihbar etmeyi unuttuğunu belirten await Eşzamansız bir yöntemden önce. Neden basitçe koymuyorsun await satırdan sonra //Assert ? - Panagiotis Kanavos
Aramadan önce beklerseniz. Test, boş bir referans istisnası aldığı için başarısız olur. - JBond
NSubstitute'un şu anda bunu ele almak için daha iyi bir yolu yoktur. Jake'in açıklamasına bakın: stackoverflow.com/a/31021430/906 Bir NSub değişikliğine değer olabilir, ben burada bir sorun yarattım: github.com/nsubstitute/NSubstitute/issues/190 - David Tchepak
bağlam dışı olabilir ama yine de tavsiye gibi hissediyorum Moq.. Moq.Verify () ile yapabileceğiniz gibi görünüyor - Vignesh.N


Cevaplar:


1.9.0 veya sonraki bir sürüme güncellediğinizde, bunları kullanabilirsiniz. await almadan NullReferenceException.


17
2017-07-20 11:35



1.8.3 piyasaya sürüldüğünde bir fikrin var mı? Şu anda bu sorunu yaşıyorum - levelnis
Bilmiyorum. David Tchepak'a ( github.com/nsubstitute/NSubstitute/issues olabilir). O NSubstitute'nin bakıcısı. - Marcio Rinaldi
@levelnis Sadece siz farkındasınız. NSubstitute’in V1.9.0 sürümü yayınlandı. Bu yığın taşması sorusundaki sorunu çözecek geliştirmeler içerir. - JBond


Ne zaman Received() yüklemesi çok karmaşık hale gelir veya yalnızca NSubstitute ile eşleşmez. Her zaman belirtilen arşivleri kullanarak yakalayabilirsiniz. geri aramaları üzerinden When().Do() veya .AndDoes(). Kullanım durumunuz için böyle bir şey giderdi

DatabaseParams receivedParms = null;
databaseHelperSub.ExecuteProcAsync(Arg.Any<DatabaseParams>())
  .Returns(Task.FromResult((object)null))
  .AndDoes(x => receivedParms = x.Arg<DatabaseParams>);

//Act      
await underTest.ExecuteAsync(request);

//Assert
receivedParms.Should().NotBeNull();
// assert your parms...

6
2017-07-15 13:05





Jake Ginnivan cevap Received beklemesi için gerekli olmadığını ancak derleyicinin bunu anlamadığını açıklar.

Uyarıyı güvenle kaldırabilirsiniz

 #pragma warning disable 4014 //for .Received await is not required, so suppress warning “Consider applying the 'await' operator”
   _service.Received(totalNumber).MyMethod(Arg.Any<ParamType>());
 #pragma warning restore 4014

2
2018-01-28 01:21