【问题标题】:Moq Throws an exception for verifyMoq 引发异常以进行验证
【发布时间】:2012-10-02 16:03:54
【问题描述】:

我是 Mocking 的新手,但这一定是我缺少的一些非常基本的东西:

下面的测试代码产生异常:

预期至少对模拟调用一次,但从未执行过:x => x.DeleteProducts(._products)\r\n\r\n已配置设置:\r\nx => x.DeleteProducts(._products) , Times.Never\r\n\r\n执行的调用:\r\nIProductRepository.DeleteProducts(System.Collections.Generic.List`1[WebApiDemo.DataAccessLayer.Product])

我单步执行控制器方法,它似乎调用了 DeleteProducts 方法...

  // Arrange
  IEnumerable<Product> _products = Helpers.ProductHelpers.CreateProducts(_numberProducts);

  Mock<IProductRepository> _productRepository = new Mock<IProductRepository>();

  _productRepository.Setup(x => x.DeleteProducts(_products));

  ProductsController controller = new ProductsController(_productRepository.Object);

  // Act
  controller.Destroy(_productViewModels);  // Destroy calls DeleteProducts

  // Assert
  _productRepository.Verify(x => x.DeleteProducts(_products));

【问题讨论】:

  • 我重新格式化了你的问题 - 它不是特别容易阅读。 (编辑待定...)

标签: moq


【解决方案1】:

DeleteProducts(_products); 是否返回 void?我认为确实如此,因此您需要将.Verifiable() 放在.Setup() 的末尾。

有了它,它应该可以正常运行,虽然我不确定为什么你有 Times.Never() 而不是 Times.Once() ??

我还提倡使用 It.IsAny&lt;T&gt; 而不是特定集合在 Setup 调用中,例如:

MyMock.Setup(x => x.MyMethod(It.IsAny<IEnumerable<Widget>>)).Verifiable()

【讨论】:

  • 我改变了 _productRepository.Setup(x => x.DeleteProducts(_products));到 _productRepository.Setup(x => x.DeleteProducts(_products)).Verifiable();得到完全相同的错误。
【解决方案2】:

除非您将模拟行为设置为 strict,否则无需进行设置。您不会从 Delete 中返回任何内容。调用验证就足够了。

有些事情从代码中并不完全显而易见。

存储库会删除 products,但控制器会销毁 productviewmodels

在最小起订量 4 中,测试应该可以工作,如果

  • _products 中的每个产品都有一个产品视图模型
  • Controller.Destroy 方法以与 _products 相同的顺序从视图模型中获取产品

我会检查 _productViewModels 是否与 _products 1:1 匹配,并检查 Destroy() 在调用 Delete() 之前如何从视图模型中提取产品

我不会使用 IsAny>(),因为您想检查这些特定产品是否已被删除,而不是其他任何产品。

[TestClass]
public class Verifying {

    public interface IProductRepository {
        void Delete(IEnumerable<Product> products);
    }

    public class ProductController {
        private IProductRepository _repository;
        public ProductController(IProductRepository repository) {
            _repository = repository;
        }
        public void Destroy(IEnumerable<Product> products) {
            _repository.Delete(products);
        }
        public void Destroy(IEnumerable<ProductViewModel> productViewModels) {
            _repository.Delete(productViewModels.Select(vm => vm.Product));
        }
    }

    public class Product {
    }

    public class ProductViewModel {
        public Product Product { get; set;}
    }


    static Verifying() {
        sProducts = new List<Product> { new Product(), new Product(), new Product() };
        sProductViewModels = new List<ProductViewModel>(sProducts.Select(p => new ProductViewModel { Product = p }));
    }

    private static List<Product> sProducts;
    private static List<ProductViewModel> sProductViewModels;

    private Mock<IProductRepository> _mockRepository;
    private ProductController CreateController() {
        _mockRepository = new Mock<IProductRepository>();
        return new ProductController(_mockRepository.Object);
    }

    [TestMethod]
    public void DestroyingProducts() {
        var controller = CreateController();
        controller.Destroy(sProducts);
        _mockRepository.Verify(mk => mk.Delete(sProducts));
    }

    [TestMethod]
    public void DestroyingProductViewModels() {
        var controller = CreateController();
        controller.Destroy(sProductViewModels);
        _mockRepository.Verify(mk => mk.Delete(sProducts));
    }

}

【讨论】:

    猜你喜欢
    • 2013-04-09
    • 1970-01-01
    • 2013-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-08
    • 1970-01-01
    • 2021-11-03
    相关资源
    最近更新 更多