単体テストには xUnit、SubSpec、FakeItEasy を使用しています。これまでに、次のような肯定的な単体テストをいくつか作成しました。
"Given a Options presenter"
.Context(() =>
presenter = new OptionsPresenter(view,
A<IOptionsModel>.Ignored,
service));
"with the Initialize method called to retrieve the option values"
.Do(() =>
presenter.Initialize());
"expect the view not to be null"
.Observation(() =>
Assert.NotNull(view));
"expect the view AutoSave property to be true"
.Observation(() => Assert.True(view.AutoSave));
しかし今、いくつかの否定的な単体テストを作成し、特定のメソッドが呼び出されず、例外がスローされることを確認したいと考えています
例えば
"Given a Options presenter"
.Context(() =>
presenter = new OptionsPresenter(view,
A<IOptionsModel>.Ignored,
service));
"with the Save method called to save the option values"
.Do(() =>
presenter.Save());
"expect an ValidationException to be thrown"
.Observation(() =>
// TODO
);
"expect an service.SaveOptions method not to be called"
.Observation(() =>
// TODO
);
FakeItEasy には MustNotHaveHappened 拡張メソッドがあり、xUnit には Assert.Throws メソッドがあることがわかります。
しかし、どうすればすべてをまとめることができますか?
テストしたい例外は、Save メソッドが呼び出されたときに発生するはずです。したがって、presenter.Save() メソッド呼び出しの周りに Assert.Throws メソッドをラップする必要があると思いますが、presenter.Save メソッドは .Do(() => ... で呼び出す必要があると思いました。
私の単体テストが以下のように見えるべきか、それとも何か他のように見えるべきか教えてください。
"Given a Options presenter"
.Context(() =>
presenter = new OptionsPresenter(view,
model,
service));
"expect the Presenter.Save call to throw an Exception"
.Observation(() =>
Assert.Throws<FluentValidation.ValidationException>(() => presenter.Save()));
"expect the Service.SaveOptions method not to be called"
.Observation(() =>
A.CallTo(() => service.SaveOptions(A<IOptionsModel>.Ignored)).MustNotHaveHappened());
どうもありがとう