如何断言某个方法仅被调用一次?

发布于 2024-12-03 14:35:19 字数 1499 浏览 0 评论 0原文

[Subject(typeof(OnceADayProcessor))]
public class When_processing_process_twice
{
    private static ICanBeProcessedOnceADay ProcessedOnceADay;

    private Establish context = () => { OnceADayProcessor.Now = () => new DateTime(2011, 1, 1, 0, 0, 0, 0); };

    private Because of = () =>
                             {
                                 ProcessedOnceADay = MockRepository.GenerateMock<ICanBeProcessedOnceADay>();
                                 ProcessedOnceADay.Process();
                                 ProcessedOnceADay.Process();
                             };

    private It should_execute = () => ProcessedOnceADay.AssertWasCalled(x => x.Expect(p => p.Process()));
    private It should_execute_only_once = () => ProcessedOnceADay.AssertWasNotCalled(x => x.Expect(p => p.Process()));
}

编辑后的解决方案:

[Subject(typeof(OnceADayProcessor))]
public class When_processing_a_process_twice_at_the_same_day
{
    static ICanBeProcessedOnceADay canBeProcessedOnceADay;

    Establish context = () =>
    {
        canBeProcessedOnceADay = A.Fake<ICanBeProcessedOnceADay>();
    };

    Because of = () =>
    {
        OnceADayProcessor.Process(canBeProcessedOnceADay);
        OnceADayProcessor.Process(canBeProcessedOnceADay);
    };

    It should_execute_only_once = () => 
        A.CallTo(() => canBeProcessedOnceADay.Process()).MustHaveHappened(Repeated.Exactly.Once);
}
[Subject(typeof(OnceADayProcessor))]
public class When_processing_process_twice
{
    private static ICanBeProcessedOnceADay ProcessedOnceADay;

    private Establish context = () => { OnceADayProcessor.Now = () => new DateTime(2011, 1, 1, 0, 0, 0, 0); };

    private Because of = () =>
                             {
                                 ProcessedOnceADay = MockRepository.GenerateMock<ICanBeProcessedOnceADay>();
                                 ProcessedOnceADay.Process();
                                 ProcessedOnceADay.Process();
                             };

    private It should_execute = () => ProcessedOnceADay.AssertWasCalled(x => x.Expect(p => p.Process()));
    private It should_execute_only_once = () => ProcessedOnceADay.AssertWasNotCalled(x => x.Expect(p => p.Process()));
}

edited solution:

[Subject(typeof(OnceADayProcessor))]
public class When_processing_a_process_twice_at_the_same_day
{
    static ICanBeProcessedOnceADay canBeProcessedOnceADay;

    Establish context = () =>
    {
        canBeProcessedOnceADay = A.Fake<ICanBeProcessedOnceADay>();
    };

    Because of = () =>
    {
        OnceADayProcessor.Process(canBeProcessedOnceADay);
        OnceADayProcessor.Process(canBeProcessedOnceADay);
    };

    It should_execute_only_once = () => 
        A.CallTo(() => canBeProcessedOnceADay.Process()).MustHaveHappened(Repeated.Exactly.Once);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

白鸥掠海 2024-12-10 14:35:19
var mock = MockRepository.GenerateMock<ICanBeProcessedOnceADay>();
mock.Expect(a => a.Process()).Repeat.Times(1);
...
mock.VerifyAllExpectations();
var mock = MockRepository.GenerateMock<ICanBeProcessedOnceADay>();
mock.Expect(a => a.Process()).Repeat.Times(1);
...
mock.VerifyAllExpectations();
绿萝 2024-12-10 14:35:19

我将对 stub.Expect()stub.VerifyAllExpectations() 的调用替换为 stub.AssertWasCalled(x => x.Process(), o =>It 中的 o.Repeat.Once())。如果您对存根有多个期望,则可以将每个断言放入一个 It 中,并让它们彼此独立地失败(或成功)。

存根的创建将进入Establish(本质上,任何依赖项和被测系统的创建是单元测试中“安排”阶段的一部分)。

另请考虑不要使用 GenerateMock 而是使用 GenerateStub,因为当您调用 Expect 指定的方法以外的其他方法时,模拟可能会导致脆弱的测试。像 FakeItEasy 这样的库通常提供更好、更容易发现的 API,更容易学习,并且会让你掉进“成功的坑”。

I would replace the calls to stub.Expect() and stub.VerifyAllExpectations() with stub.AssertWasCalled(x => x.Process(), o => o.Repeat.Once()) in the It. If you have more than one expectation against the stub you can then put each assertion in one It and have them fail (or succeed) independently of each other.

The creation of the stub would go into Establish (essentially, creation of any dependencies and the System Under Test is part of the "arrange" phase in unit testing).

Also consider not to use GenerateMock but GenerateStub as mocks will likely lead to brittle tests when you call other methods than the ones specified with Expect. Libraries like FakeItEasy generally provide better and more discoverable APIs, are easier to learn and will make you fall into the "pit of success".

芸娘子的小脾气 2024-12-10 14:35:19

如果你想确保一个方法被调用一次,你需要一个严格的模拟:

var mock = MockRepository.GenerateStrictMock<IShouldOnlyBeCalledOnce>();
mock.Expect(a => a.Process()).Repeat.Once();

sut.Process(mock)

mock.VerifyAllExpectations();

如果你只使用GenerateMock,它会执行一个“至少”检查。这也适用于 Repeats.Times(x) 。

If you want to ensure that a method is called only once, you need a strict mock:

var mock = MockRepository.GenerateStrictMock<IShouldOnlyBeCalledOnce>();
mock.Expect(a => a.Process()).Repeat.Once();

sut.Process(mock)

mock.VerifyAllExpectations();

If you just use GenerateMock, it will perform an "at least" check. This also goes for Repeats.Times(x) too.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文