如何测试使用的xUnit,SubSpec和FakeItEasy抛出的异常(How to test f

2019-07-29 21:25发布

我使用的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方法。

但我怎么把它放在一起?

该例外,我想测试时的保存方法被调用应该发生。 所以我猜我应该环绕presenter.Save()方法调用的方法Assert.Throws,但我认为presenter.Save方法应该在。做(()=>被称为...

能否请您告知,如果我的单元测试应该像下面还是其他什么东西?

"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());

非常感谢

Answer 1:

我会做这样的:

"Given a Options presenter"
    .Context(() =>
        presenter = new OptionsPresenter(view,
                                         (IOptionsModel)null,
                                         service));

"with the Save method called to save the option values"
    .Do(() => 
        exception = Record.Exception(() => presenter.Save()));

"expect an ValidationException to be thrown"
    .Observation(() =>
        Assert.IsType<ValidationException>(exception)
     );

"expect an service.SaveOptions method not to be called"
    .Observation(() =>
        A.CallTo(() => service.SaveOptions(A<IOptionsModel>.Ignored)).MustNotHaveHappened()
     );

或者更好的是,切换SubSpec为xBehave.net和引进FluentAssertions : -

"Given an options presenter"
    .x(() => presenter = new OptionsPresenter(view, (IOptionsModel)null, service));

"When saving the options presenter"
    .x(() => exception = Record.Exception(() => presenter.Save()));

"Then a validation exception is thrown"
    .x(() => exception.Should().BeOfType<ValiationException>());

"And the options model must not be saved"
    .x(() => A.CallTo(() =>
        service.SaveOptions(A<IOptionsModel>.Ignored)).MustNotHaveHappened());


Answer 2:

我没有听说过fakeItEasy或subSpec的已经(你的测试看起来很时髦,所以我可能会检查这些了:))。 不过,我使用的xUnit所以这可能会有所帮助:

我用Record.Exception与Assert.ThrowsDelegate

因此,像:

    [Fact]
    public void Test()
    {
        // Arange

        // Act
        Exception ex = Record.Exception(new Assert.ThrowsDelegate(() => { service.DoStuff(); }));

        // Assert
        Assert.IsType(typeof(<whatever exception type you are looking for>), ex);
        Assert.Equal("<whatever message text you are looking for>", ex.Message);
    }

希望帮助。



Answer 3:

这是做它FakeItEasy一种方式。

Action act = () => someObject.SomeMethod(someArgument);
act.ShouldThrow<Exception>();


文章来源: How to test for exceptions thrown using xUnit, SubSpec and FakeItEasy