【问题标题】:FakeItEasy to test domain services + UnitOfWorkFakeItEasy 测试域服务 + UnitOfWork
【发布时间】:2013-12-11 13:48:04
【问题描述】:

我开始对单元测试进行一些实验,以便我们可以将它们包含在我们的领域层中。但是我不知道我是否走在正确的道路上,因此我将解释我目前正在做什么,看看我是否走在正确的轨道上。基本上架构如下所示,域层包含域模型和域服务(例如,用户类和用户服务类)。然后域层与实现通用存储库模式和工作单元的 DAL 通信。其构造函数中的每个域服务类都接受一个 IUnitOfWork 接口,如下所示:

    public class UserService: IUserService
    {
        private readonly IUnitOfWork _unitOfWork;

        public UserService(IUnitOfWork unitOfwork)
        {
            this._unitOfWork = unitOfwork;
        }

    }

为了创建单元测试,我决定使用 FakeItEasy 框架。所以在 UserServiceTest 类中我做了以下事情:-

  private IUserService _userService;
    private const int userID = 2013;

    [TestInitialize]
    public void Initialize()
    {
    _userService = A.Fake<IUserService>();

        A.CallTo(() => _userService.GetUserById(userID)).Returns(new User
            {
                UserID = userID,
                RegistrationDate = DateTime.Now,
            });
    }


    [TestMethod]
    public void GetUserByID()
    {
        var user = _userService.GetUserById(userID);
        Assert.IsInstanceOfType(user, typeof(Domain.User));
        Assert.AreEqual(userID, user.userID);
     }

当我运行测试时,它们通过了。这是实施单元测试的正确方法吗?在我尝试不同的方法之前,FakeItEasy 因 ProxyGenerator 异常而失败。我在做的是这样的:-

 [TestInitialize]
 public void Initialize()
 {
_unitOfWork = A.Fake<IUnitOfWork>();

A.CallTo(() => _unitOfWork.UserRepository.FindById(userID)).Returns(new UserDto
    {
        UserID = userID,
        RegistrationDate = DateTime.Now,
    });


AutoMapper.Mapper.CreateMap<UserDto, User();
 }

 [TestMethod]
 public void GetUserByID()
 {
     var userService = new UserService(_unitOfWork);
     var user = userService.GetUserById(userID);
     Assert.IsInstanceOfType(user, typeof(Domain.User));
     Assert.AreEqual(userID, user.userID);
 }

这引发了以下异常:-

Result Message: 
Initialization method Initialize threw exception. System.ArgumentNullException: System.ArgumentNullException: Value cannot be null.
Parameter name: callTarget.
Result StackTrace:  
at FakeItEasy.Creation.ProxyGeneratorSelector.MethodCanBeInterceptedOnInstance(MethodInfo method, Object callTarget, String& failReason)
   at FakeItEasy.Configuration.DefaultInterceptionAsserter.AssertThatMethodCanBeInterceptedOnInstance(MethodInfo method, Object callTarget)
   at FakeItEasy.Configuration.FakeConfigurationManager.AssertThatMemberCanBeIntercepted(LambdaExpression callSpecification)
   at FakeItEasy.Configuration.FakeConfigurationManager.CallTo[T](Expression`1 callSpecification)
   at FakeItEasy.A.CallTo[T](Expression`1 callSpecification)

任何反馈将不胜感激。谢谢!

【问题讨论】:

标签: c# .net unit-testing domain-driven-design fakeiteasy


【解决方案1】:

我认为您的原始(第二个问题)测试失败了,因为_unitOfWork.UserRepositoryInitialize 中以null 的形式返回。通常 FakeItEasy 会在使用链式属性时创建一个假对象,但我猜测(我必须猜测,因为我对 UserRepository 的类型一无所知)UserRepositorytype is not fakeable。在这种情况下,你会从_unitOfWork.UserRepository 得到一个空值。

让我跳回到你的第二个测试(这是你问题中的第一个),然后我们会回到我认为你可能想在这里做的事情。

看看你的测试,

var user = _userService.GetUserById(userID);
Assert.IsInstanceOfType(user, typeof(Domain.User));
Assert.AreEqual(userID, user.userID);

我看到了一个缺陷。您直接在_userService 上调用方法,但_userService 是一个假对象,因此测试实际上不涉及任何生产代码。真的只是在锻炼 FakeItEasy。

我认为我们想要的是一种混合方法 - 可以在真正的 UserService 中运行代码,而不用担心 UserRepository。也许类似于(我在这里没有使用编译器,也不知道IUnitOfWork 上有什么方法,所以请谨慎对待)

[TestInitialize]
public void Initialize()
{
    _unitOfWork = A.Fake<IUnitOfWork>();
    A.CallTo(() => _unitOfWork.GetUserById(userID))
        .Returns(new User
        {
            UserID = userID,
            RegistrationDate = DateTime.Now,
        });
}

[TestMethod]
public void GetUserByID()
{
    var userService = new UserService(_unitOfWork);
    var user = userService.GetUserById(userID);
    Assert.IsInstanceOfType(user, typeof(Domain.User));
    Assert.AreEqual(userID, user.userID);
}

或者,如果IUnitOfWork 除了UserRepository 之外没有任何用处,那么我认为下一步将调查为什么UserRepository 的类型不可伪造(如果我的猜对了) - 它是密封的吗?它是否缺少适当且可访问的构造函数?

【讨论】:

    猜你喜欢
    • 2021-01-31
    • 2017-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多