Да, но это может быть сложно. В реализации Dispose
обычно может произойти две вещи:
Неуправляемые ресурсы высвобождаются.
В этом случае довольно сложно проверить, что код называется, например, Marshal.Release
. Возможное решение состоит в том, чтобы ввести объект, который может выполнить утилизацию, и передать ему макет во время тестирования. Что-то на этот счет:
interface ComObjectReleaser {
public virtual Release (IntPtr obj) {
Marshal.Release(obj);
}
}
class ClassWithComObject : IDisposable {
public ClassWithComObject (ComObjectReleaser releaser) {
m_releaser = releaser;
}
// Create an int object
ComObjectReleaser m_releaser;
int obj = 1;
IntPtr m_pointer = Marshal.GetIUnknownForObject(obj);
public void Dispose() {
m_releaser.Release(m_pointer);
}
}
//Using MOQ - the best mocking framework :)))
class ClassWithComObjectTest {
public DisposeShouldReleaseComObject() {
var releaserMock = new Mock<ComObjectReleaser>();
var target = new ClassWithComObject(releaserMock);
target.Dispose();
releaserMock.Verify(r=>r.Dispose());
}
}
Метод Dispose
других классов называется
Решение этой проблемы может быть не таким простым, как указано выше. В большинстве случаев реализация Dispose не является виртуальной, поэтому издеваться над ней сложно.
Один из способов заключается в том, чтобы обернуть эти другие объекты в фиктивную оболочку, аналогично тому, что пространство имен System.Web.Abstractions
делает для класса HttpContext
- то есть определяет класс HttpContextBase
со всеми виртуальными методами, которые просто делегируют вызовы методов действительному HttpContext
класс.
Дополнительные идеи о том, как сделать что-то подобное, можно найти в System.IO.Abstractions project.