одно простое решение должно было бы записать программу, чтобы сделать это для Вас. Это могло, вероятно, быть сделано довольно быстро в Python, чем-то как:
sum = 0
file = open("numbers.txt","R")
for line in file.readlines(): sum+=int(line)
file.close()
print sum
я не протестировал тот код, но это выглядит правильным. Просто измените numbers.txt на название файла, сохраните код в файл, названный sum.py, и в консольном типе в "Python sum.py"
Вы правы, говоря о перемещении GetAgentFromDatabase () в отдельный класс . Вот как я переопределил AgentRepository :
public class AgentRepository {
private IAgentDataProvider m_provider;
public AgentRepository( IAgentDataProvider provider ) {
m_provider = provider;
}
public Agent GetAgent( int agentId ) {
Agent agent = null;
using( IDataReader agentDataReader = m_provider.GetAgent( agentId ) ) {
if( agentDataReader.Read() ) {
agent = new Agent();
// set agent properties later
}
}
return agent;
}
}
где я определил интерфейс IAgentDataProvider следующим образом:
public interface IAgentDataProvider {
IDataReader GetAgent( int agentId );
}
Итак, AgentRepository - это тестируемый класс. Мы имитируем IAgentDataProvider и внедрим зависимость. (Я сделал это с помощью Moq , но вы можете легко повторить это с помощью другой структуры изоляции).
[TestFixture]
public class AgentRepositoryTest {
private AgentRepository m_repo;
private Mock<IAgentDataProvider> m_mockProvider;
[SetUp]
public void CaseSetup() {
m_mockProvider = new Mock<IAgentDataProvider>();
m_repo = new AgentRepository( m_mockProvider.Object );
}
[TearDown]
public void CaseTeardown() {
m_mockProvider.Verify();
}
[Test]
public void AgentFactory_OnEmptyDataReader_ShouldReturnNull() {
m_mockProvider
.Setup( p => p.GetAgent( It.IsAny<int>() ) )
.Returns<int>( id => GetEmptyAgentDataReader() );
Agent agent = m_repo.GetAgent( 1 );
Assert.IsNull( agent );
}
[Test]
public void AgentFactory_OnNonemptyDataReader_ShouldReturnAgent_WithFieldsPopulated() {
m_mockProvider
.Setup( p => p.GetAgent( It.IsAny<int>() ) )
.Returns<int>( id => GetSampleNonEmptyAgentDataReader() );
Agent agent = m_repo.GetAgent( 1 );
Assert.IsNotNull( agent );
// verify more agent properties later
}
private IDataReader GetEmptyAgentDataReader() {
return new FakeAgentDataReader() { ... };
}
private IDataReader GetSampleNonEmptyAgentDataReader() {
return new FakeAgentDataReader() { ... };
}
}
(Я не учел реализацию класса FakeAgentDataReader , который реализует IDataReader и является тривиальным - вам нужно только реализовать Read () и Dispose () , чтобы тесты работали.)
Цель of AgentRepository здесь, чтобы взять объекты IDataReader и преобразовать их в правильно сформированные объекты Agent . Вы можете расширить вышеуказанное тестовое устройство, чтобы проверить более интересные случаи.
После модульного тестирования AgentRepository изолированно от реальной базы данных вам потребуются модульные тесты для конкретной реализации IAgentDataProvider ], но это тема отдельного вопроса. HTH
Вы можете расширить вышеуказанное тестовое устройство, чтобы проверить более интересные случаи.После модульного тестирования AgentRepository изолированно от реальной базы данных вам потребуются модульные тесты для конкретной реализации IAgentDataProvider ], но это тема отдельного вопроса. HTH
Вы можете расширить вышеуказанное тестовое устройство, чтобы проверить более интересные случаи.После модульного тестирования AgentRepository изолированно от реальной базы данных вам потребуются модульные тесты для конкретной реализации IAgentDataProvider ], но это тема отдельного вопроса. HTH
Проблема состоит в том, чтобы решить, что такое SUT, а что - Test. В вашем примере вы пытаетесь протестировать метод Select ()
и поэтому хотите изолировать его от базы данных. У вас есть несколько вариантов:
Виртуализировать GetAgentFromDatabase ()
, чтобы вы могли предоставить производный класс с кодом для возврата правильных значений, в этом случае создавая объект, который предоставляет IDataReaderFunctionaity
без общение с БД, т.е.
класс MyDerivedExample: YourUnnamedClass
{
защищенное переопределение IDataReader GetAgentFromDatabase ()
{
вернуть новый MyDataReader ({"AgentId", "1"}, {"FirstName", "Fred"},
...);
}
}
Как Гишу предложил вместо использования отношений IsA (наследование), используйте HasA (композиция объектов), где у вас снова есть класс, который обрабатывает создание макета IDataReader
, но на этот раз без наследование.
Однако оба из них приводят к созданию большого количества кода, который просто определяет набор результатов, которые мы возвращаем при запросе. По общему признанию, мы можем сохранить этот код в тестовом коде вместо нашего основного кода, но это усилия. Все, что вы на самом деле делаете, это определяете набор результатов для конкретных запросов, и вы знаете, что действительно хорошо для этого ... База данных
Некоторое время назад я использовал LinqToSQL и обнаружил, что объекты DataContext
имеют несколько очень полезных методов, включая DeleteDatabase
и CreateDatabase
.
[FixtureSetUp ()]
public void Setup ()
{
Контекст OARsDataContext = новый MyAppDataContext (UnitTestConnection);
если (context.DatabaseExists ())
{
Console.WriteLine («Удаление существующей тестовой базы данных»);
context.DeleteDatabase ();
}
Console.WriteLine («Создание новой тестовой базы данных»);
context.CreateDatabase ();
context.SubmitChanges ();
}
Подумайте над этим. Проблема с использованием базы данных для модульных тестов заключается в том, что данные изменятся. Удалите свою базу данных и используйте свои тесты для развития ваших данных, которые можно будет использовать в будущих тестах.
Следует остерегаться двух вещей.
Убедитесь, что ваши тесты выполняются в правильном порядке. Синтаксис MbUnit для этого - [DependsOn ("NameOfPreviousTest")]
.
Убедитесь, что для конкретной базы данных выполняется только один набор тестов.
я начну выдвигать некоторые идеи и обновлю попутно:
На мой взгляд, метод GetAgentFromDatabase () не должен проверяться дополнительным тестом, потому что его код полностью покрывается тестом метода Select (). Нет никаких ветвей, по которым мог бы пройти код, поэтому нет смысла создавать здесь дополнительный тест. Если метод GetAgentFromDatabase () вызывается из нескольких методов, вы должны протестировать его самостоятельно.
Предполагая, что вы пытаетесь протестировать общедоступный метод Select класса [NoName] ..
private Hashtable GetAgentFromDatabase (int agentId)
.
public MockDB_Access : IDB_Access
{
public const string MY_NAME = "SomeName;
public Hashtable GetAgentFromDatabase(int agentId)
{ var hash = new Hashtable();
hash["FirstName"] = MY_NAME; // fill other properties as well
return hash;
}
}
// in the unit test
var testSubject = new NoName( new MockDB_Access() );
var agent = testSubject.Select(1);
Assert.AreEqual(MockDB_Access.MY_NAME, agent.FirstName); // and so on...
ИМО, вам обычно следует беспокоиться только о том, чтобы ваши общедоступные свойства / методы были проверены. Т.е. пока работает Select (int agentId) , вам обычно все равно, как он это делает через GetAgentFromDatabase (int agentId) .
То, что у вас есть, кажется разумным, как я представьте, что это можно протестировать с помощью чего-то вроде следующего (предполагая, что ваш класс называется AgentRepository)
AgentRepository aRepo = new AgentRepository();
int agentId = 1;
Agent a = aRepo.Select(agentId);
//Check a here
Что касается предлагаемых улучшений. Я бы рекомендовал разрешить изменение строки подключения AgentRepository, будь то общий или внутренний доступ.