简体   繁体   中英

Can I copy a Moq Mock implementation?

I've been using Moq and loving it, but I've come across a problem mocking some legacy code (before I try to refactor it away)

What I really want to do is have two separate mocks, with only slightly different implementation, such as the sample below.

        Mock<IFoo> fooMock = new Mock<IFoo>();
        fooMock.SetupGet(f => f.bar).Returns(7);
        fooMock.SetupGet(f => f.bar2).Returns(3);
        Mock<IFoo> fooMockClone = new Mock<IFoo>(fooMock.Behavior);
        fooMockClone.SetupGet(f => f.bar).Returns(9);

        Debug.Assert(7 == fooMock.Object.bar);
        Debug.Assert(9 == fooMockClone.Object.bar);
        Debug.Assert(3 == fooMockClone.Object.bar2);
        Debug.Assert(3 == fooMock.Object.bar2);

This is a simple example but the real code is an object with dozens of methods and I want slightly different implementation for two versions.

Thanks

I wonder in this case then if you're looking for Behavior tests. Here's a sample in Machine.Fakes with the Moq sublayer ... it allows for the nesting it seems like you're wanting, while still maintaining logical separation of the tests. Requires NuGet packages: Machine.Fakes.Moq, Machine.Specifications.Should

class IFoo_test_context : WithSubject<IFoo>
{
    Establish context = () => Subject.bar2 = 3;
}

class When_fooing_with_seven : IFoo_test_context
{
    Establish context = () => Subject.bar = 7;

    It bar_should_be_seven =()=> Subject.bar.ShouldEqual(7);
    It bar2_should_be_three =()=> Subject.bar.ShouldEqual(3);
}

class When_fooing_with_nine : IFoo_test_context
{
    Establish context = () => Subject.bar = 9;

    It bar_should_be_nine = () => Subject.bar.ShouldEqual(9);
    It bar2_should_be_three = () => Subject.bar.ShouldEqual(3);
}

Again the example is somewhat silly because it's testing the mocking behavior, but it's hard to see what you're ultimately trying to accomplish. There is no copy constructor in the way you want with Mock as far as I can tell.

You don't mock implementation details, you mock values so that you can get to a point in your code that you need to test. There's no point in writing a test that tests whether a mocked dependency outputs a value, then you're just testing moq.

Ex:

public class Stuff {
    IFoo _foo;
    IBar _bar;
    public Stuff(IFoo foo, IBar bar){
        _foo = foo;
        _bar = bar;
    }
    public void DoStuff() {
        if(_foo.HasFooage) {
            _bar.Bar = 4;
        }
    }
}

Then your test would:

...
public void test_bar_does_bar() {
    var foo = new Mock<IFoo>();
    foo.Setup(f => f.HasFooage).Returns(true);
    var bar = new Mock<IBar>();
    var stuff = new Stuff(foo.Object, bar.Object);

    stuff.DoStuff();

    Assert.That(bar.Bar, Is.EqualTo(4));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM