依赖注入 - 添加导致测试失败的Customer对象

时间:2015-01-08 20:55:56

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

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

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

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

但是,更改为以下代码(添加'Customer cust')会导致测试失败?

 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:序列不包含元素'

2 个答案:

答案 0 :(得分: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”的用户,但是你的模拟存储库中没有一个用户有这个名字

答案 1 :(得分:1)

Customer _Customer = repository.GetByName(customerName);

成员变量&#34;存储库&#34;在使用之前未初始化。您应该使用PartInvoiceController类的其他构造函数。