【问题标题】:Dependency Injection - adding Customer object causing test to fail依赖注入 - 添加客户对象导致测试失败
【发布时间】:2015-01-08 20:55:56
【问题描述】:

我在类的存储库中使用了构造函数注入,我注意到以下工作:

    public CreateInvoiceResult CreateInvoice(string Code, int qty, string Name)
    {

        if (string.IsNullOrEmpty(Code) || qty <= 0 || repository.GetByName(Name).ID <= 0)
        {
            return new CreateInvoiceResult(false);
        }

但是更改为以下代码(添加“客户客户”)会导致测试失败?

 public CreateInvoiceResult CreateInvoice(string stockCode, int quantity, string customerName)
 {
     Customer cust = repository.GetByName(Name);

     if (string.IsNullOrEmpty(Code) || qty <= 0 || cust.ID <= 0)
     {
         return new CreateInvoiceResult(false);
     }

示例测试:

请您解释一下为什么会发生这种情况以及我该如何纠正?

编辑:已使用 Moq 更新测试,以使用正确的存储库:

[TestClass]
public class MockCustomerRepositoryDBTests
{
    public MockCustomerRepositoryDBTests()
    {
        IList<Customer> customers = new List<Customer>
        {
            new Customer { ID = 1, Name = "Jim Smith",
                Address = "14 Main Road"},
            new Customer { ID = 2, Name = "Alex Smith",
                Address = "78 Avanue"},
            new Customer { ID = 3, Name = "Paul Brown",
                Address = "1 Main Road"}
        };

        // Mock the CustomerRepositoryDB Repository using Moq
        Mock<ICustomerRepository> mockCustomerRepository = new Mock<ICustomerRepository>();

        // Return a customer by Name
        mockCustomerRepository.Setup(mr => mr.GetByName(
            It.IsAny<string>())).Returns((string s) => customers.Where(
            x => x.Name == s).Single());

        // Complete the setup of the Mock Customer Repository
        this.MockCustomerRepository = mockCustomerRepository.Object;
    }

    public readonly ICustomerRepository MockCustomerRepository;

    [TestMethod]
    public void stockCodeIsNullOrEmpty()
    {
        //Arrange
        var x = new InvoiceController(MockCustomerRepository);

        //Act
        bool result = x.CreateInvoice("", 1, "test").Success;

        //Assert
        Assert.AreEqual(result, false);
    }

获取'System.InvalidOperationException:序列不包含任何元素'

【问题讨论】:

  • 你应该单独问一个关于你的起订量的问题。
  • 不需要删除所有原始问题:)。我会把它放回去。

标签: c# unit-testing dependency-injection repository


【解决方案1】:

你来电

Customer _Customer = repository.GetByName(customerName);

可能因某些异常而失败。

如果您查看您的类,您只需在此构造函数中初始化您的存储库对象:

public PartInvoiceController(ICustomerRepository custRepo)
{
    this.repository = custRepo;
}

但是您提供了一个在测试中调用的默认构造函数:

//Arrange
var x = new PartInvoiceController();

所以你的存储库永远不会初始化,所以你会得到一个空引用异常。

为什么之前没有失败?

当它是 if 语句的一部分时,它并不重要,因为它从未执行过,因为 string.IsNullOrEmpty(stockCode) 为真,其他条件使用 conditional-or operator (||) 组合,如果它会短路评估条件即使没有评估所有条件,也可以判断条件是真还是假。

因此输入了 if 语句,并且从未评估其他条件,因此为 null 的存储库是从未执行过的代码。

要更正它,您需要提供要在测试中使用的存储库(存根或模拟),或者在默认构造函数中创建默认存储库,或者恢复为原始代码(只要您不关心在此测试中未初始化存储库)。

像这样改变你的测试:

[TestMethod]
public void stockCodeIsNullOrEmpty()
{
    ICustomerRepository testRepository = //create a test repository here
    //Arrange
    var x = new PartInvoiceController(testRespository);

    //Act
    bool result = x.CreatePartInvoice("", 1, "test").Success;

    //Assert
    Assert.AreEqual(result, false);
}

编辑

你真的应该问另一个关于你的模拟问题的问题,但基本上你正在寻找一个名为“test”的用户,但你在模拟存储库中的用户都没有这个名字

【讨论】:

  • 感谢您的帮助 - 我认为它因“System.NullReferenceException:对象引用未设置为对象的实例而失败。” - 我该如何纠正?
  • 我在答案末尾提供了有关如何更正的信息。您需要在测试中提供一个存储库,否则该类将使用哪个存储库来获取用户?
  • 没问题。如果您发现答案有帮助,那么您应该使用答案左上角的向上箭头对其进行投票。如果答案解决了您的问题,您应该通过单击投票箭头下方的勾号来接受它。请参阅Why Vote,并考虑使用the tour 以熟悉该站点的工作方式。优秀的网站公民通常会提出更好的问题并获得更好的答案。
  • OK 需要 15 名代表来投票 - 虽然会在上面编辑,但仍有问题。
  • 没问题。欢迎来到stackoverflow,您在提出第一个问题方面做得很好。不过,如果您问了一个单独的问题,您也可以得到该问题的支持。
【解决方案2】:
Customer _Customer = repository.GetByName(customerName);

成员变量“repository”在使用前未初始化。您应该使用 PartInvoiceController 类的其他构造函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-10
    • 1970-01-01
    • 2019-04-07
    • 2017-09-16
    • 2016-10-04
    相关资源
    最近更新 更多