代码之家  ›  专栏  ›  技术社区  ›  Rob Gray

模拟参数的属性更改-使用moq

  •  3
  • Rob Gray  · 技术社区  · 16 年前

    我正在使用moq模拟我的存储库层,以便进行单元测试。

    当数据库插入成功时,存储库层插入方法会更新实体的ID属性。

    调用insert方法时,如何配置moq以更新实体的id属性?

    存储库代码:

    void IAccountRepository.InsertAccount(AccountEntity account);
    

    单元测试:

    [TestInitialize()]
    public void MyTestInitialize() 
    {
        accountRepository = new Mock<IAccountRepository>();
        contactRepository = new Mock<IContactRepository>();
        contractRepository = new Mock<IContractRepository>();
        planRepository = new Mock<IPlanRepository>();
        generator = new Mock<NumberGenerator>();
    
        service = new ContractService(contractRepository.Object, accountRepository.Object, 
                        planRepository.Object, contactRepository.Object, generator.Object);   
    }
    
    
    [TestMethod]
    public void SubmitNewContractTest()
    {
        // Setup Mock Objects
        planRepository
            .Expect(p => p.GetPlan(1))
            .Returns(new PlanEntity() { Id = 1 });
    
        generator
            .Expect(p => p.GenerateAccountNumber())
            .Returns("AC0001");
    
        // Not sure what to do here? 
        // How to mock updating the Id field for Inserts?
        //                                                 
        // Creates a correctly populated NewContractRequest instance
        NewContractRequest request = CreateNewContractRequestFullyPopulated();
    
        NewContractResponse response = service.SubmitNewContract(request);
        Assert.IsTrue(response.IsSuccessful);
    }
    

    ContractService类(WCF服务约定)的实现段。

    AccountEntity account = new AccountEntity()
    {
        AccountName = request.Contact.Name,
        AccountNumber = accountNumber,
        BillingMethod = BillingMethod.CreditCard,
        IsInvoiceRoot = true,
        BillingAddressType = BillingAddressType.Postal,
        ContactId = request.Contact.Id.Value
    };
    
    accountRepository.InsertAccount(account);
    if (account.Id == null)
    {
        // ERROR
    }
    

    如果这方面的信息有点欠缺,我深表歉意。我今天才开始学习moq和mocking框架。交流电

    2 回复  |  直到 16 年前
        1
  •  5
  •   Matt Hamilton    16 年前

    您可以使用回调方法模拟副作用。类似:

    accountRepository
        .Expect(r => r.InsertAccount(account))
        .Callback(() => account.ID = 1);
    

    这是未经测试的,但它是沿着正确的路线。

        2
  •  2
  •   Rob Gray    16 年前

    我不确定这将如何工作,因为帐户是在方法中创建的,所以当我将ID值设置为1时,它不是我要引用的实例。

    也许我的设计有缺陷,我应该检查iaccountrepository.insertaccount实现中的id>0,然后返回bool(如果可以的话)。不过,我在插入一个帐户时遇到了一个问题,该帐户有一个需要插入的相关对象(以及一个生成的ID)。

    我发现这是我问题的答案

    accountRepository
        .Expect(p => p.InsertAccount(It.Is<AccountEntity>(x => x.Id == null)))
        .Callback<AccountEntity>(a => a.Id = 1);
    

    谢谢。