0

ドメイン層にそれらを含めることができるように、単体テストの実験を始めました。ただし、正しい道をたどっているかどうかはわかりません。したがって、正しい道を進んでいるかどうかを確認するために現在行っていることを説明します。基本的なアーキテクチャは次のようなもので、ドメイン モデルとドメイン サービス (例: User クラスと UserService クラス) を含む Domain Layer があります。次に、ドメイン層は、作業単位とともに汎用リポジトリ パターンを実装する 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)

どんなフィードバックでも大歓迎です。ありがとう!

4

1 に答える 1

0

のように_unitOfWork.UserRepository戻ってくるため、元の(問題の2番目の)テストが失敗したと思います。通常、 FakeItEasy は、チェーンされたプロパティが使用されると偽のオブジェクトを作成しますが、私は推測しています ( の型について何も知らないため、推測する必要があります)その型は fakeable ではありません。その場合、 から null が返されます。nullInitializeUserRepositoryUserRepository_unitOfWork.UserRepository

2 番目のテスト (質問の最初のテスト) に戻りましょう。次に、ここでやりたいと思うことに戻ります。

あなたのテストを見て、

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(私の推測が正しかった場合) - それは封印されていますか? 適切でアクセス可能なコンストラクターが不足していませんか?

于 2013-12-11T15:44:37.673 に答える