Это действительно зависит от того, что вы пытаетесь сделать, именно так:
Тем не менее, я постараюсь предоставить некоторую информацию для вашего решения.
В UNIX fork()
создает клон вашего процесса из того места, где вы назвали fork. То есть, если у меня следующий процесс:
#include <unistd.h>
#include <stdio.h>
int main()
{
printf( "hi 2 u\n" );
int mypid = fork();
if( 0 == mypid )
printf( "lol child\n" );
else
printf( "lol parent\n" );
return( 0 );
}
Вывод будет выглядеть следующим образом:
hi 2 u
lol child
lol parent
Когда вы fork()
, pid, возвращаемый в потомке, равен 0, а pid, возвращаемый в родительском элементе, является pid ребенка. Обратите внимание, что "hi2u" печатается только один раз ... родителем .
execve()
и его семейство функций почти всегда используются с fork().
execve()
и т. П. Перезаписывают текущий стековый кадр именем приложения, которое вы передаете ему. execve()
почти всегда используется с fork()
, когда вы разветвляете дочерний процесс, и если вы родитель, вы делаете все, что вам нужно, и если вы ребенок, вы запускаете новый процесс. execve()
также почти всегда используется с waitpid()
- waitpid берет pid дочернего процесса и, буквально, ждет , пока ребенок не завершит работу, и вернет вам статус выхода ребенка.
Используя эту информацию, вы сможете написать очень простую оболочку; тот, который принимает имена процессов в командной строке и запускает процессы, которые вы ему сообщаете. Конечно, оболочки делают больше, чем, например, ввод и вывод по трубопроводам, но вы должны быть в состоянии выполнить основы, используя fork()
, execve()
и waitpid()
.
ПРИМЕЧАНИЕ. Это * * nix! Это НЕ будет работать в Windows.
Надеюсь, это помогло.
Я только что обнаружил, что этого можно добиться, не используя виртуальные методы в этих двух методах - он защищает методы от переопределения при генерации заглушки.
public class TimeMachine
{
public virtual DateTime GetCurrentDateTime(){ return DateTime.Now; };
public DateTime GetCurrentDate(){ return GetCurrentDateTime().Date; };
public TimeSpan GetCurrentTime(){ return GetCurrentDateTime().TimeOfDay; };
}
Теперь тест проходит.
Измените свой TimeMachine
на абстрактный класс:
public abstract class TimeMachine
{
public abstract DateTime GetCurrentDateTime();
public DateTime GetCurrentDate(){ return GetCurrentDateTime().Date; };
public TimeSpan GetCurrentTime(){ return GetCurrentDateTime().TimeOfDay; };
}
Для производственных целей вы можете создать конкретную реализацию TimeMachine
следующим образом:
public class SystemTimeMachine : TimeMachine
{
public override DateTime GetCurrentDateTime()
{
return DateTime.Now;
}
}
Все классы, использующие TimeMachine
, теперь можно внедрить с помощью абстракции, но в производстве вы можете связать свой граф объектов с помощью SystemTimeMachine
.
I'm not sure which version of Rhino.Mocks you're using, but what I would do is make only the GetCurrentDateTime() method virtual (like an earlier poster suggested), then create your mock object using PartialMock(). There are lots of ways to set things up, but the following should work:
var mocks = new MockRepository();
var time = mocks.PartialMock<TimeMachine>();
using (mocks.Record())
{
Expect.Call(time.GetCurrentDateTime()).Return(new DateTime(2009, 11, 25, 12, 0, 0));
}
using (mocks.Playback())
{
Assert.AreEqual(new DateTime(2009, 11, 25), time.GetCurrentDate());
}
Заглушка просто предоставляет стандартные ответы на вызовы методов и свойств, он ничего не знает о фактической реализации TimeMachine. Боюсь, вам придется настраивать результаты для каждого из трех методов (или для конкретного метода, который вы хотите протестировать).