C# FakeiTasy测试域服务+;工作单元

C# FakeiTasy测试域服务+;工作单元,c#,.net,unit-testing,domain-driven-design,fakeiteasy,C#,.net,Unit Testing,Domain Driven Design,Fakeiteasy,我开始做一些单元测试的实验,这样我们就可以将它们包括在我们的领域层中。然而,我不知道我是否走上了正确的道路,因此我要解释一下我目前正在做什么,看看我是否走上了正确的道路。基本上,该体系结构如下所示:域层包含域模型和域服务(例如用户类和用户服务类)。然后域层与DAL通信,DAL与工作单元一起实现通用存储库模式。其构造函数中的每个域服务类都接受一个IUnitOfWork接口,如下所示: public class UserService: IUserService {

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

    public class UserService: IUserService
    {
        private readonly IUnitOfWork _unitOfWork;

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

    }
为了创建单元测试,我决定使用Fakeitesy框架。因此,在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);
     }
如有任何反馈,将不胜感激。谢谢

我认为您最初的(问题中的第二个)测试失败了,因为
\u unitOfWork.UserRepository
初始化中返回为
null
。通常,FakeiTesy在使用链接属性时会创建一个假对象,但我在猜测(我不得不猜测,因为我不知道
UserRepository
)的类型是
UserRepository
)。在这种情况下,您将从
\u unitOfWork.UserRepository
返回空值

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

看看你的测试

var user = _userService.GetUserById(userID);
Assert.IsInstanceOfType(user, typeof(Domain.User));
Assert.AreEqual(userID, user.userID);
我看到了一个缺陷。您正在直接调用
\u userService
上的方法,但是
\u userService
是一个伪对象,因此测试实际上不涉及任何生产代码。这真的只是做作而已

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

[测试初始化]
公共无效初始化()
{
_unitOfWork=A.Fake();
A.CallTo(()=>_unitOfWork.GetUserById(userID))
.Returns(新用户
{
UserID=UserID,
注册日期=日期时间。现在,
});
}
[测试方法]
public void GetUserByID()
{
var userService=newuserservice(_unitOfWork);
var user=userService.GetUserById(userID);
Assert.IsInstanceOfType(user,typeof(Domain.user));
aresequal(userID,user.userID);
}

,如果除了
UserRepository
之外,
IUnitOfWork
上没有任何有用的东西,那么我想下一步应该是调查为什么
UserRepository
的类型是不可伪造的(如果我的猜测是正确的话)-它是密封的吗?它是否缺少适当且可访问的构造函数?

您的
UserService
看起来像存储库。我会把它们看作是DAL的一部分。当域模型知道抽象
IUnitOfWork
时,这可能没什么问题,但是您的域服务与(,)中的描述不同。
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)
var user = _userService.GetUserById(userID);
Assert.IsInstanceOfType(user, typeof(Domain.User));
Assert.AreEqual(userID, user.userID);
[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);
}