1
votes

There is a need to mock System.Printing.PrintQueue for some test. Currently I'm getting this error when trying to create PrintQueue for presumably existing virtual printer (new PrintQueue(new PrintServer(), "Microsoft XPS Document Writer")):

System.Printing.PrintQueueException: PrintTicket provider failed to bind to printer. Win32 error: -2147467231
    at MS.Internal.Printing.Configuration.PTProvider..ctor(String deviceName, Int32 maxVersion, Int32 clientVersion)
   at MS.Internal.Printing.Configuration.PTProviderBase.Create(String deviceName, Int32 maxVersion, Int32 clientVersion)
   at System.Printing.PrintTicketManager..ctor(String deviceName, Int32 clientPrintSchemaVersion)
   at System.Printing.PrintQueue.GetPrintCapabilities()

Note the error is not about missing printer. I can shim PrintTicket that is on the top of stack using Fakes, but it's absolutely not clear which method is throwing. And PrintQueue is not a managed class (resides in PrintQueue.cpp). Any ideas?
edit
Googled around a bit, still no luck getting around this issue: https://connect.microsoft.com/VisualStudio/feedback/details/690455/printqueue-getprintcapabilities-throws-when-incorrect-driver-is-configured-for-printer-on-print-server http://www.infragistics.com/community/forums/t/50736.aspx http://petterisbetter.com/michael/index.php/2008/09/29/printticket-provider-failed-to-retrieve-

1
If you can't test it then you could always create a "wrapper class" which you could mock... It's not as pure as mocking the object directly, but it would solve the problem quickly.David Kirkland
@DavidKirkland I would happily do it if returned objects had some common interface and/or default constructors.Jaded
Would it be feasible to create your own IPrintTicket interface, and wrap up the returned objects in a class implementing it? I presume there is some common information that is returned. Maybe I've misunderstood the exact details here, but you should still be able to wrap the return type...David Kirkland

1 Answers

-1
votes

Solving the problem required extracting and implementing a few "partial" interfaces.

/// <summary>
/// Contract for PrintCapabilities
/// </summary>
public interface IPrintCapabilities
{
    /// <summary>
    /// Gets CollactionCapability.
    /// </summary>
    IEnumerable<Collation> CollationCapability { get; }

    /// <summary>
    /// Gets MaxCopyCount.
    /// </summary>
    int? MaxCopyCount { get; }

    /// <summary>
    /// Gets OrientedPageMediaHeight.
    /// </summary>
    double? OrientedPageMediaHeight { get; }

    /// <summary>
    /// Gets OrientedPageMediaWidth.
    /// </summary>
    double? OrientedPageMediaWidth { get; }

    /// <summary>
    /// Gets PageMediaSizeCapability.
    /// </summary>
    IEnumerable<PageMediaSize> PageMediaSizeCapability { get; }

    /// <summary>
    /// Gets PageOrientationCapability.
    /// </summary>
    IEnumerable<PageOrientation> PageOrientationCapability { get; }

    /// <summary>
    /// Gets DuplexingCapability.
    /// </summary>
    IEnumerable<Duplexing> DuplexingCapability { get; }

    /// <summary>
    /// Gets InputBinCapability.
    /// </summary>
    IEnumerable<InputBin> InputBinCapability { get; }

    /// <summary>
    /// Gets OutputColorCapability.
    /// </summary>
    IEnumerable<OutputColor> OutputColorCapability { get; }

    /// <summary>
    /// Gets PageOrderCapability.
    /// </summary>
    IEnumerable<PageOrder> PageOrderCapability { get; }

    /// <summary>
    /// Gets StaplingCapability.
    /// </summary>
    IEnumerable<Stapling> StaplingCapability { get; }
}

/// <summary>
/// Contract for PrintQueue
/// </summary>
public interface IPrintQueue
{
    /// <summary>
    /// Gets IsOffline flag.
    /// </summary>
    bool IsOffline { get; }

    /// <summary>
    /// Gets FullName.
    /// </summary>
    string FullName { get; }

    /// <summary>
    /// Refreshes PrintQueue.
    /// </summary>
    void Refresh();

    /// <summary>
    /// Gets or sets DefaultPrintTicket.
    /// </summary>
    IPrintTicket DefaultPrintTicket { get; set; }

    /// <summary>
    /// Gets PrintCapabilities.
    /// </summary>
    /// <returns></returns>
    IPrintCapabilities GetPrintCapabilities();
}

/// <summary>
/// Contract for PrintQueueCollection.
/// </summary>
public interface IPrintQueueCollection : IEnumerable
{
}

/// <summary>
/// Interface that describes all classes implementing PrintServer operations.
/// </summary>
public interface IPrintServer
{
    /// <summary>
    /// Gets the collection of print queues of the specific types.
    /// </summary>
    /// <param name="enumerationFlag">Array of types of print queues.</param>
    /// <returns>Print queues collection.</returns>
    IPrintQueueCollection GetPrintQueues(EnumeratedPrintQueueTypes[] enumerationFlag);

    /// <summary>
    /// Returns a reference of default print queue of LocalPrintServer.
    /// </summary>
    /// <returns>Print queue.</returns>
    IPrintQueue GetDefaultPrintQueue();
}

/// <summary>
/// Contract for PrintTicket
/// </summary>
public interface IPrintTicket
{
    /// <summary>
    /// Gets or sets PageOrientation.
    /// </summary>
    PageOrientation? PageOrientation { get; set; }

    /// <summary>
    /// Gets or sets Duplexing.
    /// </summary>
    Duplexing? Duplexing { get; set; }

    /// <summary>
    /// Gets or sets Stapling.
    /// </summary>
    Stapling? Stapling { get; set; }

    /// <summary>
    /// Gets or sets PageOrder.
    /// </summary>
    PageOrder? PageOrder { get; set; }

    /// <summary>
    /// Gets or sets OutputColor.
    /// </summary>
    OutputColor? OutputColor { get; set; }

    /// <summary>
    /// Gets or sets Collation.
    /// </summary>
    Collation? Collation { get; set; }

    /// <summary>
    /// Gets or sets PageMediaSize.
    /// </summary>
    PageMediaSize PageMediaSize { get; set; }
}