Moq抛出一个例外进行验证

时间:2012-10-02 16:03:55

标签: moq

我是Mocking的新手,但这肯定是我缺少的基本内容:

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

  

模拟上的预期调用至少一次,但从未执行过:x => x.DeleteProducts(._ products)\ r \ n \ r \ n配置设置:\ r \ n \ n => 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));

2 个答案:

答案 0 :(得分:0)

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

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

我还提倡使用It.IsAny<T>而不是特定集合进行安装调用,例如:

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

答案 1 :(得分:0)

除非您将模拟行为设置为严格,否则无需进行设置。您没有从删除中返回任何内容。对Verify的调用就足够了。

代码中有些事情并不完全明显。

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

在Moq 4中,如果

,测试应该有效
  • 您有_products
  • 中每个产品的产品视图模型
  • Controller.Destroy方法以与_products
  • 相同的顺序从viewmodels获取产品

我会检查_productViewModels与_products的1:1匹配,并检查Destroy()在调用Delete()之前如何从viewmodels中提取产品

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

[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));
    }

}