Ideally I'd try and split the responsibilities of this dependency (could even pass the same object as two dependencies into the SUT, once as IDetails and once as ICollection?).
If that's not going to work for you, you could try a custom class to wrap what you're testing. Make non-virtual, concrete members that will be ignored by NSub, and then keep the members you want to substitute virtual or abstract. A little bit more work but I think it makes what's happening fairly clear:
public class TestMyDetails : IMyDetails
{
//Concrete list. Non-virtual.
public List<int> BackingList;
public IEnumerator<int> GetEnumerator() { return BackingList.GetEnumerator(); }
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
public void Add(int item) { BackingList.Add(item); }
public void Clear() { BackingList.Clear(); }
public bool Contains(int item) { return BackingList.Contains(item); }
public void CopyTo(int[] array, int arrayIndex) { BackingList.CopyTo(array, arrayIndex); }
public bool Remove(int item) { return BackingList.Remove(item); }
public int Count { get { return BackingList.Count; } }
public bool IsReadOnly { get { return false; } }
//Members to sub. Must be virtual or abstract to be intercepted by NSub
public virtual string Name { get; set; }
public virtual string Details { get; set; }
}
[Test]
public void Example()
{
var details = Substitute.For<TestMyDetails>();
details.BackingList = new List<int> {1, 2, 3, 4};
details.Name.Returns("foo");
details.Name.ShouldBe("foo");
details.Count.ShouldBe(4);
}
Messy, but the best I can come up with at the moment.