在测试服务层时模拟对象 [英] Mocking objects when testing service layer

查看:64
本文介绍了在测试服务层时模拟对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好!


我正在尝试在我们的项目中使用PEX,Silverlight客户端连接到WCF服务,这些服务使用NHibernate调用另一个连接到数据库的服务层。 / p>

在我用来测试我的服务层之前:

 

 public void TestGetCustomersForAdvisor()
{
             //安排
   &NBSP; &NBSP; &NBSP; &NBSP;   IRepository repository = MockRepository.GenerateStub< IRepository>();
   &NBSP; &NBSP; &NBSP; &NBSP;   ICustomerRepository customerRepository = MockRepository.GenerateStub< ICustomerRepository>();

   &NBSP; &NBSP; &NBSP; &NBSP;   Advisor advisor1 = new Advisor {Id = 1,FirstName =" Ad1"};
   &NBSP; &NBSP; &NBSP; &NBSP;   Advisor advisor2 = new Advisor {Id = 2,FirstName =" Ad2"};
   &NBSP; &NBSP; &NBSP; &NBSP; &NBSP;列表与LT;客户和GT; customers = new List< Customer>();
   &NBSP; &NBSP; &NBSP; &NBSP;   customers.Add(new Customer {Advisor = advisor1,Id = 1});
   &NBSP; &NBSP; &NBSP; &NBSP;   customers.Add(new Customer {Advisor = advisor2,Id = 2});
  repository.Expect(X => x.GetAll<客户>())返回(客户)。
   &NBSP; &NBSP; &NBSP; &NBSP;   repository.Expect(x => x.Get< Advisor>(advisor1.Id))。Return(advisor1);

   &NBSP; &NBSP; &NBSP; &NBSP;   // act
   &NBSP; &NBSP; &NBSP; &NBSP;   CustomerServices服务=新的CustomerServices(customerRepository,repository);
   &NBSP; &NBSP; &NBSP; &NBSP; &NBSP;列表与LT; CustomerDto> recieved =(List< CustomerDto>)services.GetCustomersForAdvisor(advisor1.Id);

   &NBSP; &NBSP; &NBSP; &NBSP;   //断言
   &NBSP; &NBSP; &NBSP; &NBSP;   Assert.AreEqual(收到[0] .Id,1);
   &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; repository.VerifyAllExpectations();
}


换句话说,在测试服务层时,我能够模拟下面的DataAccess层的行为并且真的只是测试服务方法。


现在当我使用PEX和参数化测试时,我最终得到的方法如下:


< pre style ="color:#000000; font-family:Verdana,Arial,Helvetica,sans-serif; font-size:10px; margin:8px; border:1px solid#d0d0d0"> [PexMethod]
public IList< ; CustomerDto> GetCustomersForAdvisor([PexAssumeUnderTest] CustomerServices目标,int advisorID)
{
   &NBSP; &NBSP; &NBSP; &NBSP; &NBSP;&IList的LT; CustomerDto> result = target.GetCustomersForAdvisor(advisorID);
   &NBSP; &NBSP; &NBSP; &NBSP;  返回结果;
   &NBSP; &NBSP; &NBSP; &NBSP;   // TODO:向方法CustomerServicesTest.GetCustomersForAdvisor(CustomerServices,Int32)添加断言
}

 


现在,我在这里如何提供或设置作为CustomerService类一部分的存储库的行为?


或者可能这不是假设使用PEX的情况?任何建议都会有所帮助,因为我有点迷失。


提前致谢,


Honza

  


honga.super6.cz


解决方案

好的,现在这是一个愚蠢的问题。我找到了解决方案。


首先我可以更改参数化测试方法的签名,因此不需要将目标传递给方法,而是方法可以配置目标。 / p>

现在我可以(或者可能必须?)使用Moles来配置我的服务对象,而不是使用MockRepository:


这是测试方法:


  public  IList< CustomerDto> GetCustomersForAdvisor( int  advisorID)
{
   &NBSP; &NBSP; &NBSP; &NBSP;   Advisor advisor = _repository.Get< Advisor>(advisorID);
   &NBSP; &NBSP; &NBSP; &NBSP; &NBSP;&IList的LT; CustomerDto> customers  =  _repository.GetAll< Customer>()。其中​​(x => x.Advisor == advisor).Select(x => x.ToDto())。ToList();
   &NBSP; &NBSP; &NBSP; &NBSP;   返回客户;
}


Hello!

I am trying to make use of PEX on our projects which Silverlight client connected to WCF services which are calling another Service layer connected to DB using NHibernate.

Before I use to test my Service layer like this:

public void TestGetCustomersForAdvisor()
{
            //arrange
            IRepository repository = MockRepository.GenerateStub<IRepository>();
            ICustomerRepository customerRepository = MockRepository.GenerateStub<ICustomerRepository>();

            Advisor advisor1 = new Advisor { Id = 1, FirstName = "Ad1"};
            Advisor advisor2 = new Advisor {Id=2,FirstName = "Ad2"};
            List<Customer> customers = new List<Customer>();
            customers.Add(new Customer { Advisor = advisor1, Id = 1});
            customers.Add(new Customer {Advisor = advisor2, Id = 2});
	   repository.Expect(x=>x.GetAll<Customer>()).Return(customers);
            repository.Expect(x => x.Get<Advisor>(advisor1.Id)).Return(advisor1);

            //act
            CustomerServices services = new CustomerServices(customerRepository, repository);
            List<CustomerDto> recieved = (List<CustomerDto>)services.GetCustomersForAdvisor(advisor1.Id);

            //assert
            Assert.AreEqual(recieved[0].Id, 1);
            repository.VerifyAllExpectations();
}

In other words when testing the Service layer I was able to mock the behaviour of the DataAccess layer bellow and really just test the service method.

Now when I am using PEX and I Parametrized testing in general I end up with method which looks like this:

[PexMethod]
public IList<CustomerDto> GetCustomersForAdvisor([PexAssumeUnderTest]CustomerServices target, int advisorID)
{
            IList<CustomerDto> result = target.GetCustomersForAdvisor(advisorID);
            return result;
            // TODO: add assertions to method CustomerServicesTest.GetCustomersForAdvisor(CustomerServices, Int32)
}

 

Now here how can I provide or set the behaviour of the repositories which are part of the CustomerService class?

Or maybe this is not the case for which PEX is suppose to be used? Any suggestion would be helpful because I am kind of lost here.

Thanks in advance,

Honza


honga.super6.cz

解决方案

Ok, now it was a silly question. I found the solution.

First I can change the signature of the parametrized test method, so there is no need to pass the target to the method, instead the method can configure the target.

Now instead of using MockRepository, I can (or maybe have to?) use Moles to configure my services object:

Here is the tested method:

public IList<CustomerDto> GetCustomersForAdvisor(int advisorID)
{
            Advisor advisor = _repository.Get<Advisor>(advisorID);
            IList<CustomerDto> customers  =  _repository.GetAll<Customer>().Where(x=>x.Advisor == advisor).Select(x=>x.ToDto()).ToList();
            return customers;
}


这篇关于在测试服务层时模拟对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆