은 테스트 전용 Sqlite 데이터베이스를 아주 쉽게 삽입 할 수 있으며 아래 코드와 같이 리팩터링합니다. 그러나 당신은 어떻게 결과를 주장합니까? 비즈니스 개체는 someOtherClass
에게 전달됩니다. ISomeOtherClass
을 삽입하는 경우 해당 클래스의 작업을 볼 수 있어야합니다.그것은 약간의 고통처럼 보입니다. 당신은 단지 테스트를위한 IRepository
구현, 또는 가짜를 조롱 할 수 있도록이 클래스에서 코드의 일부를 제거하는 것 인 IRepository
를 사용
public class KillerApp
{
private String databasePath;
private ISomeOtherClass someOtherClass;
public KillerApp(String databasePath, ISomeOtherClass someOtherClass)
{
this.databasePath = databasePath;
this.someOtherClass = someOtherClass;
}
public void DoThatThing()
{
var connection = OpenSqliteConnection(databasePath);
var allGizmoRecords = connection.Query(...);
var businessObjects = TransformIntoBizObjs(allGizmoRecords);
someOtherClass.HandleNewBizObjs(businessObjects);
}
}
[TestClass]
public class When_Doing_That_Thing
{
private const String DatabasePath = /* test path */;
private ISomeOtherClass someOtherClass = new SomeOtherClass();
private KillerApp app;
[TestInitialize]
public void TestInitialize()
{
app = new KillerApp(DatabasePath, someOtherClass);
}
[TestMethod]
public void Should_convert_all_gizmo_records_to_busn_objects()
{
app.DoThatThing();
Assert.AreEqual(someOtherClass.Results, /* however you're confirming */);
}
}
.
public class KillerApp
{
private IRepository<BusinessObject> repository;
private ISomeOtherClass someOtherClass;
public KillerApp(IRepository<BusinessObject> repository, ISomeOtherClass someOtherClass)
{
this.repository = repository;
this.someOtherClass = someOtherClass;
}
public void DoThatThing()
{
BusinessObject[] entities = repository.FindAll();
someOtherClass.HandleNewBizObjs(entities);
}
}
[TestClass]
public class When_Doing_That_Thing
{
private const String DatabasePath = /* test path */;
private IRepository<BusinessObject> repository;
private ISomeOtherClass someOtherClass = new SomeOtherClass();
private KillerApp app;
[TestInitialize]
public void TestInitialize()
{
repository = new BusinessObjectRepository(DatabasePath);
app = new KillerApp(repository, someOtherClass);
}
[TestMethod]
public void Should_convert_all_gizmo_records_to_busn_objects()
{
app.DoThatThing();
Assert.AreEqual(someOtherClass.Results, /* however you're confirming */);
}
}
그러나 이것은 여전히 꽤 부담 스럽습니다. 두 가지 이유가 있습니다. 1) Repository 패턴은 getting somebad press입니다. 최근에는 Repository에 대해 알고있는 사람이 Ayende입니다. 그리고 2) 뭐하는거야 자신의 데이터 액세스를 쓰고!? 및 ActiveRecord을 사용하십시오!
[ActiveRecord] /* You define your database schema on the object using attributes */
public BusinessObject
{
[PrimaryKey]
public Int32 Id { get; set; }
[Property]
public String Data { get; set; }
/* more properties */
}
public class KillerApp
{
private ISomeOtherClass someOtherClass;
public KillerApp(ISomeOtherClass someOtherClass)
{
this.someOtherClass = someOtherClass;
}
public void DoThatThing()
{
BusinessObject[] entities = BusinessObject.FindAll() /* built-in ActiveRecord call! */
someOtherClass.HandleNewBizObjs(entities);
}
}
[TestClass]
public class When_Doing_That_Thing : ActiveRecordTest /* setup active record for testing */
{
private ISomeOtherClass someOtherClass = new SomeOtherClass();
private KillerApp app;
[TestInitialize]
public void TestInitialize()
{
app = new KillerApp(someOtherClass);
}
[TestMethod]
public void Should_convert_all_gizmo_records_to_busn_objects()
{
app.DoThatThing();
Assert.AreEqual(someOtherClass.Results, /* however you're confirming */);
}
}
결과는 훨씬 더 작은 클래스와 더 쉽게 변경할 수있는 비즈니스 개체 및 데이터 계층입니다. 데이터베이스 호출을 조롱 할 필요조차 없으며 테스트 데이터베이스 (메모리 내, 심지어는)를 사용하도록 ActiveRecord를 구성하고 초기화 할 수 있습니다.
Ayende는 IRepository를 사용하여 신중한 것을 알고 있습니다. 나는 여기에 질문을하기 전에 그 글을 참고했다. 나는 NHibernate 나 LINQ-to-Sqlite를 사용할 수 있다고 생각했지만 잔인 함을 느꼈습니다. 이것은 타사 데이터베이스와 정확히 한 번 대화하는 일회용 클래스입니다 (예 : 파일 -> 가져 오기 ...). 이런 간단한 일을하기 위해 ORM을 설정하는 것은 과도한 행동으로 보입니다. –
어쨌든,이 답변을 주셔서 감사합니다. 나는 그것을 투표했다. 그것은 내 문제를 해결하는데 도움이되고 AR이나 NHibernate 또는 다른 ORM과 함께하지는 않을지라도 몇 가지 아이디어를 제공한다. –
어떻게하면 모든 일을 할 수 있습니다. –