문제

최근 AutoFixture+AutoMoq을 사용하기 시작했고 다음 인스턴스를 생성하려고 합니다. Func<IDbConnection> (즉, 연결 팩토리)

var fixture = new Fixture().Customize(new AutoMoqCustomization());
var connectionFactory = fixture.Create<Func<IDbConnection>>();

이것은 꽤 잘 작동하는 것 같습니다:

  1. 테스트 중인 내 시스템은 대리자를 호출할 수 있으며 이는 모의 객체를 얻습니다. IDbConnection
  2. 그런 다음 전화를 걸 수 있습니다. CreateCommand, 그러면 나에게 조롱거리가 될 것입니다 IDbCommand
  3. 그런 다음 전화를 걸 수 있습니다. ExecuteReader, 그러면 나에게 조롱거리가 될 것입니다 IDataReader

이제 모의 객체에 대해 추가 설정을 수행하고 싶습니다. IDataReader, 예를 들어 반환하도록 설정 true 언제 Read() 호출됩니다.

내가 읽은 것에서 나는 사용해야합니다 Freeze 이를 위해:

var dataReaderMock = fixture.Freeze<Mock<IDataReader>>();

dataReaderMock.Setup(dr => dr.Read())
                      .Returns(true);

그래도 이건 내 기대에 미치지 못하는 것 같다.내가 전화할 때 IDbCommand.ExecuteReader, 방금 동결/설정한 리더와 다른 리더를 얻게 됩니다.

예는 다음과 같습니다.

var fixture = new Fixture().Customize(new AutoMoqCustomization());

var dataReaderMock = fixture.Freeze<Mock<IDataReader>>();
dataReaderMock.Setup(dr => dr.Read())
              .Returns(true);

//true - Create<IDataReader> retrieves the data reader I just mocked
Assert.AreSame(dataReaderMock.Object, fixture.Create<IDataReader>());

//false - IDbCommand returns a different instance of IDataReader
Assert.AreSame(dataReaderMock.Object, fixture.Create<IDbCommand>().ExecuteReader());

내가 도대체 ​​뭘 잘못하고있는 겁니까?다음과 같은 다른 설비를 어떻게 구하나요? IDbCommand, 조롱된 인스턴스를 사용하려면 IDataReader?

도움이 되었습니까?

해결책

3.20.0부터 다음을 사용할 수 있습니다. AutoConfiguredMoqCustomization.그러면 멤버의 반환 값이 AutoFixture에 의해 생성되도록 모든 모의 객체가 자동으로 구성됩니다.

예: IDbConnetion.CreateCommand 반환하도록 자동으로 구성됩니다. IDbCommand 고정 장치에서 IDbCommand.ExecuteReader 반환하도록 자동으로 구성됩니다. IDataReader 고정 장치에서.

이제 모든 테스트를 통과해야 합니다.

var fixture = new Fixture().Customize(new AutoConfiguredMoqCustomization());

var dataReaderMock = fixture.Freeze<Mock<IDataReader>>();
dataReaderMock.Setup(dr => dr.Read())
              .Returns(true);

//all pass
Assert.Same(dataReaderMock.Object, fixture.Create<IDataReader>());
Assert.Same(dataReaderMock.Object, fixture.Create<IDbCommand>().ExecuteReader());
Assert.Same(dataReaderMock.Object, fixture.Create<IDbConnection>().CreateCommand().ExecuteReader());
Assert.Same(dataReaderMock.Object, fixture.Create<Func<IDbConnection>>()().CreateCommand().ExecuteReader());

다른 팁

당신은해야 Freeze 그만큼 Mock<IDbCommand> 또한 – 기존 객체를 반환하도록 모의 객체를 (스텁으로) 설정합니다. dataReaderMock.Object 사례.

테스트의 정렬 단계에 다음을 추가하면 테스트가 통과됩니다.

var dbCommandStub = 
    fixture
        .Freeze<Mock<IDbCommand>>()
        .Setup(x => x.ExecuteReader())
        .Returns(dataReaderMock.Object);

Nikos의 해결책이 작동하는 동안 나는 조롱을 권장하지 않을 것입니다.

내 의견에서 테스트가 이해하기가 어렵고 유지 보수가 어려울 것이며, 테스트가 당신에게 주어야 할 확신을주지 않을 것입니다.

데이터베이스가 느려지지만 데이터 레이어를 테스트하여 데이터 계층을 테스트하는 것이 좋습니다.

조롱을위한 모범 사례와 관련 하여이 기사를 읽는 것이 좋습니다. http://codebetter.com/JEREMYMILLER / 2006 / 01 / 10 / BEST-and-and-~ 최악의 관행 - 모의 - 개체 /

다른 사람들을 조롱하지 마십시오 : http:///aspiringcantman.com/2012/04/01 / TDD-Best-Practices-mok-mock /

나는 당신의 정확한 상황을 모르지만 어쨌든 나는 이것을 공유하고 싶었다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top