模拟调用的异常是0次,但我可以正确地看到执行的调用

时间:2016-07-07 08:51:15

标签: c# unit-testing mocking moq autofixture

这是我的单元测试的简化版本

var service = Fixture.Freeze<IService>();
var outerService = Fixture.Create<OuterService>();

var testObject = Fixture.Create<TestObject>();

outerService.Notify(testObject);
Mock.Get(service).Verify(s => s.SendNotification(It.IsAny<String>(), It.IsAny<TestObject>(), null), Times.Once);

请注意:

outerService.Notify(testObject)

内部调用

IService.SendNotification(string testObject.Name, testObject, extraObject = null)

上述情况会导致测试失败,抱怨说:

Expected invocation 1 time,but was 0 times: 
s => s.SendNotification(It.IsAny<String>(), It.IsAny<TestObject>(), null)
No setups configured.

Performed invocations:
IService.SendNotification("testObject", UnitTest.TestObject, null)

我不明白,执行的调用看起来和预期的调用完全一样,这里发生了什么?

修改

好的,如果我在测试中直接致电service.SendNotification ,它会有效,但如果我通过outerService调用它,它将无效吗?为什么呢?

更新

道歉,如果我的问题不够清楚,这里有关于如何配置Fixture对象的更多细节:

Fixture fixture = new Fixture();
fixture.Customize(new AutoConfiguredMoqCustomization());
fixture.Customize(new SpecimenCustomization());

对于细节来说,这真的是关于它的,我希望这不是一个复杂的场景。

1 个答案:

答案 0 :(得分:1)

当您致电Mock.GetThe received mocked instance was not created by Moq时,会发生此错误。这意味着模拟服务有No setups configured

鉴于这种简化的假设。

public class OuterService {
    private IService service;

    public OuterService(IService service) {
        this.service = service;
    }

    public void Notify(TestObject testObject) {
        service.SendNotification(testObject.Name, testObject, extraObject: null);
    }
}

public interface IService {
    void SendNotification(string name, TestObject testObject, object extraObject);
}

public class TestObject {
    public string Name { get; set; }
} 

以下测试应该有效

//Arrange
var service = Mock.Of<IService>();
var outerService = new OuterService(service);
var testObject = new TestObject { Name = "testObject" };

//Act
outerService.Notify(testObject);

//Assert
Mock.Get(service).Verify(s => s.SendNotification(It.IsAny<String>(), It.IsAny<TestObject>(), null), Times.Once);

Moq现在知道服务对象,可以从上面创建的模拟实例中提取模拟设置。

更新

意识到您正在使用 AutoFixture 并且经过一些研究后能够重新创建您的问题。您需要自定义 AutoFixture 才能使用 Moq

检查Auto-Mocking with Moq如何执行此操作。

根据上述相同的假设,以下工作。

//Arrange
var fixture = new Fixture();
fixture.Customize(new Ploeh.AutoFixture.AutoMoq.AutoMoqCustomization());

var service = fixture.Freeze<IService>();
var outerService = fixture.Create<OuterService>();
var testObject = fixture.Create<TestObject>();

//Act
outerService.Notify(testObject);

//Assert
Mock.Get(service).Verify(s => s.SendNotification(It.IsAny<String>(), It.IsAny<TestObject>(), null), Times.Once);