unit testing - readable substitution of IEnumerable of Interfaces -
i have following interfaces
public interface iribboncommandsprovider { ienumerable<iribboncommand> getribboncommands(); } public interface iribboncommand { string group { get; } string tab { get; } string name { get; } string image { get; } void execute(); }
and follwing substitution code:
public class tabsviewmodeltests { [fact] public void initialize_buildscorrectribbontree() { var commands = substitute.for<iribboncommandsprovider>(); commands.getribboncommands().returns( new[] { new ribboncommand { tab = "tab1", group = "group1", name = "name1" }, new ribboncommand { tab = "tab1", group = "group1", name = "name2" }, new ribboncommand { tab = "tab2", group = "group1", name = "name3" }, new ribboncommand { tab = "tab2", group = "group2", name = "name3" } }); ... } private class ribboncommand : iribboncommand { public string group { get; set; } public string tab { get; set; } public string name { get; set; } public string image { get; set; } public void execute() {} } }
using nsubstitute, there clever way rid of stub ribboncommand class (that nothing fake iribboncommand
implementation - , that's nsubstitute's job) and still have list of fake ribbon commands easily readable above?.
i can't come readable way using nsubsitute's .returns()
fluent method without ending lot more (and unreadable) code.
update: cool nsubstitute extension method this. don't know if , how can built:
public static configuredcall returnsmany<t>( ienumerable<t> value, action<t> configurethis, params action<t>[] configurethese) { ... }
it used this:
commands.getribboncommands().returnsmany( subst => { subst.tab.returns("tab1"); subst.group.returns("group1"); subst.name.returns("name1"); }, subst => { subst.tab.returns("tab1"); subst.group.returns("group1"); subst.name.returns("name2"); }, subst => { subst.tab.returns("tab2"); subst.group.returns("group1"); subst.name.returns("name3"); }, subst => { subst.tab.returns("tab2"); subst.group.returns("group1"); subst.name.returns("name3"); });
i think you've got — quite succinct , clear.
if want rid of class can use substitute creation method iribboncommand
:
private iribboncommand create(string tab, string group, string name) { var cmd = substitute.for<iribboncommand>(); cmd.tab.returns(tab); cmd.group.returns(group); cmd.name.returns(name); return cmd; } [fact] public void initialize_buildscorrectribbontree() { var ribboncommands = new[] { create("tab1", "group1", "name1"), create("tab1", "group1", "name2"), create("tab2", "group1", "name3"), create("tab2", "group1", "name4") }; var commands = substitute.for<iribboncommandsprovider>(); commands.getribboncommands().returns(ribboncommands); // ... }
this doesn't buy much, although mean test code more protected changes iribboncommand
interface (e.g. additional property not require changing test code), , means can check received calls , stub other calls on individual items.
aside: can use argument names if want more closely match original code:
create(tab: "tab1", group: "group1", name: "name1"),
Comments
Post a Comment