最小起订量与方法不匹配。 Moq.MockException: mock 上的所有调用都必须有相应的设置

Moq doesn't match methods. Moq.MockException: All invocations on the mock must have a corresponding setup

最小起订量与模拟方法不匹配。

异常:

Exception thrown: 'Moq.MockException' in Moq.dll: 'IMongoRepository.FindByVrcId("b4cb3139-90aa-4477-979b-d893e3317386") invocation failed with mock behavior Strict. All invocations on the mock must have a corresponding setup.'

这是我的单元测试:

public class OfferHandlerTest : TestBase
{
    Mock<IMongoRepository> repositoryMock = new Mock<IMongoRepository>(MockBehavior.Strict);
    OfferHandler? offerHandler;

    [Fact]
    public void HandleTest()
    {
        JObject? offerFullDocument = null;
        using (var sr = new StreamReader("Data/offer_full_document.json"))
        {
            var reader = new JsonTextReader(sr);
            offerFullDocument = JObject.Load(reader);
        }

        var kafkaPayload = new KafkaMessagePayloadSourceConnector();
        kafkaPayload.OperationType = Constants.Mongo_OperationType_Update;
        kafkaPayload.FullDocument = offerFullDocument;

        OfferService service = new OfferService(repositoryMock.Object);
        offerHandler = new OfferHandler(service, this.ServiceConfiguration);

        offerHandler.Handle(kafkaPayload);

        DHOffer offer = new DHOffer();
        offer.Version = 1;

        // THIS SETUP FAILS
        repositoryMock.Setup(s => s.FindByVrcId<DHOffer>(It.IsAny<string>())).Returns(It.IsAny<DHOffer>());

        repositoryMock.Verify(s => s.FindAndUpdate<DHOffer>(It.IsAny<DHOffer>()), Times.Once);
    }
}

这是句柄方法:

public void Handle(KafkaMessagePayloadSourceConnector kafkaPayload)
{
    VRCOffer offer = kafkaPayload!.FullDocument!.ToObject<VRCOffer>()!;

    if (kafkaPayload!.OperationType!.Equals(Constants.Mongo_OperationType_Update))
    {
        offerService.updateOfferStatus(OfferMapper.MapToDataHubModel(offer), offer.MasterId);
    }
}

最后是服务方式:

public class OfferService
{
    private readonly IMongoRepository offerRepository;

    public OfferService(IMongoRepository offerRepository)
    {
        this.offerRepository = offerRepository;
    }
    
    internal void updateOfferStatus(DHOffer offer, string vrcMasterId)
    {
        // THIS SHOULD RETURN MOCKED OBJECT
        DHOffer existingOffer = offerRepository.FindByVrcId<DHOffer>(vrcMasterId);
        existingOffer.ModifiedDate = DateTime.Now.ToString();
        existingOffer.AdditionalInformation.Status = offer?.AdditionalInformation?.Status!;

        offerRepository.FindAndUpdate(existingOffer);
    }
}

我尝试在 Return() 方法中使用 It.IsAny<DHOffer>(),但我得到了同样的异常。

您的问题是您在运行使用模拟对象之后设置最小起订量。到那时已经太晚了。您只需要在开始时 运行 .Setup(...) 命令。

还值得注意的是,如果多个测试需要不同的设置,则使用共享模拟可能会出现问题。有些工具可以 运行 并行测试,这可能会把事情搞砸,或者以不同的顺序进行测试,这可能会导致事情变得更脆弱。