如何验证方法是否被调用?

发布于 2024-12-14 15:54:07 字数 2165 浏览 3 评论 0原文

我有一个依赖于 ITicketApiAdapterICreateService 类。我尝试注册一个模拟 ITicketAdaper,以便在创建匿名创建服务时注入它。

因此,在设置中,我为票证适配器注册了这个:

Fixture.Register(() =>
    {
        var ticketApiAdapter = new Mock<ITicketApiAdapter>();
        ticketApiAdapter
            .Setup( x => x.AddTicketComment(
                It.IsAny<User>(), 
                It.IsAny<Customer>(), 
                It.IsAny<TicketComment>()))
        .Returns(new SaveResult
                        {
                            Success = true, 
                            Id = Fixture.CreateAnonymous<Guid>().ToString()
                        });

        return ticketApiAdapter;
    });

Fixture.Register(() => new CreateService(Fixture.CreateAnonymous<Mock<ITicketApiAdapter>>().Object));

根据我的理解,这应该“冻结” ICreateServiceMock ,以便当我请求时一个匿名实例,这是我注册的。

我有一个如下所示的测试:

[TestMethod]
public void CreateServiceCallsAddTicketComment()
{
    var apiTicketAdapter = Fixture.CreateAnonymous<Mock<ITicketApiAdapter>>();
    var createTicketRequest = Fixture.CreateAnonymous<CreateTicketComment>();
    var createService = Fixture.CreateAnonymous<CreateService>();

    var results = createService.CreateTicketComment(createTicketRequest);

    apiTicketAdapter
        .Verify(x => x.AddTicketComment(
            It.IsAny<User>(), 
            It.IsAny<Customer>(), 
            It.IsAny<TicketComment>()), 
        Times.Once());

    Assert.IsTrue(results.All(x => x.Success));
    Assert.IsTrue(results.All(x => x.Errors.Count == 0));

}

我希望 apiTicketAdapter 是我注册的,以便我可以验证该方法是否被调用。如果我单步执行,TicketApiAdapter 就会被调用,但 Moq 说它没有。

编辑

这是我得到的错误:

CreateServiceCallsAddTicketComment 抛出异常: Moq.MockException:预期对模拟调用一次,但为 0 次:x => x.AddTicketComment(It.IsAny(), It.IsAny(), It.IsAny())

配置的设置:x => x.AddTicketComment(It.IsAny(), It.IsAny()、It.IsAny())、Times.Never 否 执行的调用。

I have a ICreateService class that has dependency on ITicketApiAdapter. I've tried registering a mock ITicketAdaper so that it gets injected when I create an anonymous create service.

So, in setup, I have this register for the ticket adapter:

Fixture.Register(() =>
    {
        var ticketApiAdapter = new Mock<ITicketApiAdapter>();
        ticketApiAdapter
            .Setup( x => x.AddTicketComment(
                It.IsAny<User>(), 
                It.IsAny<Customer>(), 
                It.IsAny<TicketComment>()))
        .Returns(new SaveResult
                        {
                            Success = true, 
                            Id = Fixture.CreateAnonymous<Guid>().ToString()
                        });

        return ticketApiAdapter;
    });

Fixture.Register(() => new CreateService(Fixture.CreateAnonymous<Mock<ITicketApiAdapter>>().Object));

From my understanding, that should "freeze" both the ICreateService and Mock<ITicketApiAdapter> so that when I request an anonymous instance, it's the one I registered.

I have a test that looks like this:

[TestMethod]
public void CreateServiceCallsAddTicketComment()
{
    var apiTicketAdapter = Fixture.CreateAnonymous<Mock<ITicketApiAdapter>>();
    var createTicketRequest = Fixture.CreateAnonymous<CreateTicketComment>();
    var createService = Fixture.CreateAnonymous<CreateService>();

    var results = createService.CreateTicketComment(createTicketRequest);

    apiTicketAdapter
        .Verify(x => x.AddTicketComment(
            It.IsAny<User>(), 
            It.IsAny<Customer>(), 
            It.IsAny<TicketComment>()), 
        Times.Once());

    Assert.IsTrue(results.All(x => x.Success));
    Assert.IsTrue(results.All(x => x.Errors.Count == 0));

}

I expect the apiTicketAdapter to be the one I registered so that I can verify the method is called. If I step through, the TicketApiAdapter is called, but Moq says it wasn't.

Edit

This is the error I get:

CreateServiceCallsAddTicketComment threw exception:
Moq.MockException: Expected invocation on the mock once, but was 0
times: x => x.AddTicketComment(It.IsAny(), It.IsAny(),
It.IsAny())

Configured setups: x => x.AddTicketComment(It.IsAny(),
It.IsAny(), It.IsAny()), Times.Never No
invocations performed.

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

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

发布评论

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

评论(1

笑饮青盏花 2024-12-21 15:54:07

当您注册代码块时,每次 Fixture 实例解析请求的类型时,都会调用该代码块。这意味着它没有被冻结。如果您想冻结某些内容,冻结重载之一通常更容易使用。

更好的是,既然您似乎正在使用 Moq,我可以建议使用 AutoMoq 扩展< /a>?

这将使您能够将测试重写为如下所示:

[TestMethod]
public void CreateServiceCallsAddTicketComment(new AutoMoqCustomization());
{
    var fixture = new Fixture().Customize()
    var apiTicketAdapter = fixture.Freeze<Mock<ITicketApiAdapter>>();
    ticketApiAdapter
        .Setup( x => x.AddTicketComment(
            It.IsAny<User>(), 
            It.IsAny<Customer>(), 
            It.IsAny<TicketComment>()))
        .Returns(new SaveResult
        {
            Success = true, 
            Id = Fixture.CreateAnonymous<Guid>().ToString()
        });

    var createTicketRequest = fixture.Freeze<CreateTicketComment>();
    var createService = fixture.CreateAnonymous<CreateService>();

    var results = createService.CreateTicketComment(createTicketRequest);

    apiTicketAdapter
        .Verify(x => x.AddTicketComment(
            It.IsAny<User>(), 
            It.IsAny<Customer>(), 
            It.IsAny<TicketComment>()), 
        Times.Once());

    Assert.IsTrue(results.All(x => x.Success));
    Assert.IsTrue(results.All(x => x.Errors.Count == 0));

}

假设 CreateTicketRequest 使用构造函数注入或属性注入。

When you Register a code block, that code block is going to be invoked every time the Fixture instance resolves the requested type. This means that it's not frozen. If you want to Freeze something, one of the Freeze overloads are often easier to use.

Better yet, since you seem to be using Moq, may I suggest using the AutoMoq extension?

That would enable you to rewrite the test to something like this:

[TestMethod]
public void CreateServiceCallsAddTicketComment(new AutoMoqCustomization());
{
    var fixture = new Fixture().Customize()
    var apiTicketAdapter = fixture.Freeze<Mock<ITicketApiAdapter>>();
    ticketApiAdapter
        .Setup( x => x.AddTicketComment(
            It.IsAny<User>(), 
            It.IsAny<Customer>(), 
            It.IsAny<TicketComment>()))
        .Returns(new SaveResult
        {
            Success = true, 
            Id = Fixture.CreateAnonymous<Guid>().ToString()
        });

    var createTicketRequest = fixture.Freeze<CreateTicketComment>();
    var createService = fixture.CreateAnonymous<CreateService>();

    var results = createService.CreateTicketComment(createTicketRequest);

    apiTicketAdapter
        .Verify(x => x.AddTicketComment(
            It.IsAny<User>(), 
            It.IsAny<Customer>(), 
            It.IsAny<TicketComment>()), 
        Times.Once());

    Assert.IsTrue(results.All(x => x.Success));
    Assert.IsTrue(results.All(x => x.Errors.Count == 0));

}

That's assuming that CreateTicketRequest uses Constructor Injection or Property Injection.

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