Reputation: 1596
I'm trying to test the following method:
public void SaveDashboardToPersistentDashboard(
Dashboard dashboard, PersistentDashboard persistentDashboard)
{
using (MemoryStream stream = new MemoryStream())
{
dashboard.SaveToXml(stream);
persistentDashboard.Definition = stream.ToArray();
persistentDashboard.Name = dashboard.Title.Text;
_unitOfWork.CommitChanges();
}
}
The method takes a DevExpress Dashboard, calls SaveToXml
(passing in a MemoryStream
) and then writes the stream array to a PersistentDashboard
POCO's Definition
property.
I have no control over the Dashboard class, but would like to mock the SaveToXml
method to exclude Dashboard method behaviour from the test. This would involve taking the internal stream and writing an array of known bytes into it.
I'm new to Moq, and can't work out how to change the contents of the stream passed into SaveToXml - at least not without passing the stream into the SaveDashboardToPersistentDashboard
method. The stream is incidental to the method's behaviour, so I'm not particularly keen on passing it as a parameter.
Is there any way to achieve what I'm trying to do?
Upvotes: 0
Views: 1359
Reputation: 1241
This is an issue with your design. Not with the mocking library you use.
Directly accessing frameworks is often a bad idea if you want your code to be testable. That even includes the .NET framework itself. While using DateTime
is usually safe, using File
can already become a huge pain.
What I'd suggest is to create wrapper classes for the DevExpress
classes you use. Then extract interfaces from them which you use in your business logic. You can mock them in your tests no problem then.
Something like that:
public interface IDashboard
{
void SaveToXml(Stream stream);
}
public class DashboardWrapper : IDashboard
{
private readonly Dashboard dashboard = new Dashboard();
public void SaveToXml(Stream stream)
{
this.dashboard.SaveToXml(stream);
}
}
You can use an abstract factory or IoC-Container to create those wrappers.
ETA: Not sure how those Dashboard
objects are instantiated. Alternatively, give the wrapper a constructor that takes a Dashboard
instance and implement an operator
for implicit conversion that uses that constructor.
Upvotes: 3