モックされたオブジェクトによってイベントが提起されたことを確認しました
-
24-10-2019 - |
質問
私のユニットテストでは、モックされたオブジェクトによってイベントが提起されていることを確認するにはどうすればよいですか。
ビュー(ui) - > viewmodel-> dataprovider-> serviceProxyがあります。 ServiceProxyは、Serivce Operationを非同期に呼び出します。 Async操作が完了すると、DataProviderのメソッドが呼び出されます(コールバックメソッドはメソッドパラメーターとして渡されます)。その後、Callbackメソッドは、どのViewModelが聴いているかを上げてイベントにします。
ViewModelテストの場合、DataProviderをmockして、DataProviderによって提起されたイベント用にハンドラーが存在することを確認します。 DataProvider Iをテストするときは、serviceproxyをmockしますが、コールバックメソッドが呼び出され、イベントが発生する方法をテストするにはどうすればよいですか。
Rhinomock 3.5とAAA構文を使用しています
ありがとう
-DataProvider-
public partial class DataProvider
{
public event EventHandler<EntityEventArgs<ProductDefinition>> GetProductDefinitionCompleted;
public void GetProductDefinition()
{
var service = IoC.Resolve<IServiceProxy>();
service.GetProductDefinitionAsync(GetProductDefinitionAsyncCallback);
}
private void GetProductDefinitionAsyncCallback(ProductDefinition productDefinition, ServiceError error)
{
OnGetProductDefinitionCompleted(this, new EntityEventArgs<ProductDefinition>(productDefinition, error));
}
protected void OnGetProductDefinitionCompleted(object sender, EntityEventArgs<ProductDefinition> e)
{
if (GetProductDefinitionCompleted != null)
GetProductDefinitionCompleted(sender, e);
}
}
-ServiceProxy-
public class ServiceProxy : ClientBase<IService>, IServiceProxy
{
public void GetProductDefinitionAsync(Action<ProductDefinition, ServiceError> callback)
{
Channel.BeginGetProductDefinition(EndGetProductDefinition, callback);
}
private void EndGetProductDefinition(IAsyncResult result)
{
Action<ProductDefinition, ServiceError> callback =
result.AsyncState as Action<ProductDefinition, ServiceError>;
ServiceError error;
ProductDefinition results = Channel.EndGetProductDefinition(out error, result);
if (callback != null)
callback(results, error);
}
}
解決
書くべき2つの異なるユニットテストがあるように聞こえます:
サービスプロキシユニットテスト:このテストにより、ServiceProxyに送信されるコールバックがAsync Callの完了時に呼び出されることを確認します。
データプロバイダーのユニットテスト:このテストにより、特定の方法が呼び出されたときにイベントが発生することを確認します(サブスクライバーがあると仮定します)。
どちらを助けていますか?
編集:
アイテム#1の場合、モッキングが必要だとは思いません。呼び出されたときにいくつかの変数をtrueに設定するコールバックを提供するだけです。
// arrange
IServiceProxy serviceProxy = new ServiceProxy();
bool callbackMade;
// act
serviceProxy.GetDataAsync(() => callbackMade = true);
// assert
Assert.IsTrue(callbackMade);
アイテム#2の場合、繰り返しますが、ユニットテストでイベントを購読して、イベントが呼び出されていることを確認してください。
// arrange
DataProvider dp = new DataProvider();
bool eventRaised;
dp.DataReturned += (s,e) => eventRaised = true;
// act
dp.DoSomethingThatShouldRaiseEvent();
// assert
Assert.IsTrue(eventRaised)
私はあなたのイベント/コールバックの署名がわからないので、私はちょうどいくつかの推測をしました。
他のヒント
次の例は、ANを設定します IService
たとえに渡されるコールバックを単純に呼び出すスタブ IService.AsyncOperationWithCallBack(Action callback)
呼ばれています。
// arrange
var serviceStub = MockRepository.GenerateStub<IService>();
serviceStub.Stub(x => x.AsyncOperationWithCallBack(Arg<Action>.Is.NotNull))
.WhenCalled(
invokation =>
{
var callback = (Action)invokation.Arguments[0];
callback();
});
var dataProvider = new DataProvider(serviceStub);
// act
bool raised = false;
dataProvider.MyEvent += delegate { raised = true; };
dataProvider.DoSomething();
// assert
serviceStub.AssertWasCalled(
x=>x.AsyncOperationWithCallBack(Arg<Action>.Is.NotNull));
Assert.IsTrue(raised);