노력 단위 테스트를위한 Shim DbContext ctor

effort entity-framework microsoft-fakes shim unit-testing

문제

대신 다른 생성자 호출을 반환하는 var context = new MyDbContext() 를 가로 채고 싶습니다.

EFfort 의 가장 큰 장점 은 단위 테스팅을위한 쉬운 메모리 내장 데이터베이스를 설정하는 것입니다.

var connection = Effort.DbConnectionFactory.CreateTransient();
var testContext = new MyDbContext(connection);

그런 다음 해당 context 를 저장소에 삽입해야합니다.

var connection = Effort.DbConnectionFactory.CreateTransient();
var testContext = new MyDbContext(connection);

그냥 var context = new MyDbContext() 인터셉트하여 testContext 반환 할 수 있습니까?

var connection = Effort.DbConnectionFactory.CreateTransient();
var testContext = new MyDbContext(connection);

수락 된 답변

(편집 : 나는 이것이 실제로 다른 ctor 호출을 반환하지 않는다는 것을 깨달았다.

그것을 알아 냈다. 당신이 그것을하는 방법을 아는 경우에 충분히 간단합니다 :

        [TestMethod]
        public void Should_have_a_name_like_this()
        {
            // Arrange
            var connection = Effort.DbConnectionFactory.CreateTransient();
            ShimSolrDbContext.Constructor = context => new SolrDbContext(connection);

            // Act


            // Assert

        }

그리고 평소처럼 EFfort는 DbContext 클래스에서 다음 생성자를 필요로합니다.

        [TestMethod]
        public void Should_have_a_name_like_this()
        {
            // Arrange
            var connection = Effort.DbConnectionFactory.CreateTransient();
            ShimSolrDbContext.Constructor = context => new SolrDbContext(connection);

            // Act


            // Assert

        }

그러나 Repo가 특별한 Transient 연결을 알지 못한다는 것을 의미합니다.

        [TestMethod]
        public void Should_have_a_name_like_this()
        {
            // Arrange
            var connection = Effort.DbConnectionFactory.CreateTransient();
            ShimSolrDbContext.Constructor = context => new SolrDbContext(connection);

            // Act


            // Assert

        }

인기 답변

가능한 옵션은 두 가지입니다. 팩토리를 사용하거나 Aspect 지향 프로그래밍 (예 : PostSharp)

이 기사를 참조 : http://www.progware.org/Blog/post/Interception-and-Interceptors-in-C-(Aspect-oriented-programming).aspx

PostSharp (AOP) 사용

PostSharp는 훌륭한 툴이며 가능한 가장 깨끗한 인터 셉션을 가능하게합니다 (객체 생성 및 / 또는 인터페이스를위한 공장을 가지고 있지 않더라도 클래스 및 객체 생성을 전혀 변경하지 않음을 의미 함)하지만 무료 라이브러리는 아닙니다. 런타임에 프록시를 생성하는 대신 컴파일 타임에 코드를 삽입하므로 메소드를 가로 채기 위해 초기 프로그램을 매끄럽게 변경합니다.
.....
여기서 멋진 점은 코드에서 다른 것을 변경하지 않으므로 new 키워드를 사용하여 객체를 생성 할 수 있다는 것입니다.

DI 및 공장 패턴 사용

필자는 개인적으로 공장 패턴 접근 방식을 선호하지만, 클래스에 종속성을 주입해야하는 것처럼 보입니다.

public interface IDbContextFactory<T> where T : DbContext {
    T Create();
}

public class TestDbContextFactory : IDbContextFactory<MyDbContext> {
    public MyDbContext Create() {
        var connection = Effort.DbConnectionFactory.CreateTransient();
        var testContext = new MyDbContext(connection);
        return testContext;
    }
}

public class FooRepository {
    MyDbContext _context;
    public FooRepository(IDbContextFactory<MyDbContext> factory) { 
        _context = factory.Create(); 
    }
}



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.